1 /*
2  * Copyright 1997-2001 by Alan Hourihane, Wigan, England.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of Alan Hourihane not be used in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific, written prior permission.  Alan Hourihane makes no representations
11  * about the suitability of this software for any purpose.  It is provided
12  * "as is" without express or implied warranty.
13  *
14  * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  *
22  * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
23  *           Dirk Hohndel, <hohndel@suse.de>
24  *	     Stefan Dirsch, <sndirsch@suse.de>
25  *	     Michel Dänzer, <michdaen@iiic.ethz.ch>
26  *	     Sven Luther, <luther@dpt-info.u-strasbg.fr>
27  *
28  * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen,
29  * Siemens Nixdorf Informationssysteme and Appian Graphics.
30  */
31 
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35 
36 #include "fb.h"
37 #include "micmap.h"
38 #include "xf86.h"
39 #include "xf86_OSproc.h"
40 #include "xf86Pci.h"
41 #include "xf86cmap.h"
42 #include "shadowfb.h"
43 #include "fbdevhw.h"
44 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
45 #include "xf86RAC.h"
46 #include "xf86Resources.h"
47 #endif
48 #include "xf86int10.h"
49 #include "dixstruct.h"
50 #include "vbe.h"
51 
52 #include "compiler.h"
53 #include "mipointer.h"
54 
55 #include "pm3_regs.h"
56 #include "glint_regs.h"
57 #include "IBM.h"
58 #include "TI.h"
59 #include "glint.h"
60 
61 #ifdef XFreeXDGA
62 #define _XF86DGA_SERVER_
63 #include <X11/extensions/xf86dgaproto.h>
64 #endif
65 
66 #include "globals.h"
67 #ifdef HAVE_XEXTPROTO_71
68 #include <X11/extensions/dpmsconst.h>
69 #else
70 #define DPMS_SERVER
71 #include <X11/extensions/dpms.h>
72 #endif
73 
74 
75 #define DEBUG 0
76 
77 #if DEBUG
78 # define TRACE_ENTER(str)       ErrorF("glint: " str " %d\n",pScrn->scrnIndex)
79 # define TRACE_EXIT(str)        ErrorF("glint: " str " done\n")
80 # define TRACE(str)             ErrorF("glint trace: " str "\n")
81 #else
82 # define TRACE_ENTER(str)
83 # define TRACE_EXIT(str)
84 # define TRACE(str)
85 #endif
86 
87 static const OptionInfoRec *	GLINTAvailableOptions(int chipid, int busid);
88 static void	GLINTIdentify(int flags);
89 static Bool	GLINTProbe(DriverPtr drv, int flags);
90 static Bool	GLINTPreInit(ScrnInfoPtr pScrn, int flags);
91 static Bool	GLINTScreenInit(SCREEN_INIT_ARGS_DECL);
92 static Bool	GLINTEnterVT(VT_FUNC_ARGS_DECL);
93 static void	GLINTLeaveVT(VT_FUNC_ARGS_DECL);
94 static Bool	GLINTCloseScreen(CLOSE_SCREEN_ARGS_DECL);
95 static Bool	GLINTSaveScreen(ScreenPtr pScreen, int mode);
96 
97 /* Optional functions */
98 static void	GLINTFreeScreen(FREE_SCREEN_ARGS_DECL);
99 static ModeStatus GLINTValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
100 				 Bool verbose, int flags);
101 
102 /* Internally used functions */
103 static Bool	GLINTMapMem(ScrnInfoPtr pScrn);
104 static Bool	GLINTUnmapMem(ScrnInfoPtr pScrn);
105 static void	GLINTSave(ScrnInfoPtr pScrn);
106 static void	GLINTRestore(ScrnInfoPtr pScrn);
107 static Bool	GLINTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
108 static void 	GLINTBlockHandler(BLOCKHANDLER_ARGS_DECL);
109 
110 /*
111  * This is intentionally screen-independent.  It indicates the binding
112  * choice made in the first PreInit.
113  */
114 static int GLINTEntityIndex = -1;
115 static Bool FBDevProbed = FALSE;
116 
117 /*
118  * This contains the functions needed by the server after loading the driver
119  * module.  It must be supplied, and gets passed back by the SetupProc
120  * function in the dynamic case.  In the static case, a reference to this
121  * is compiled in, and this requires that the name of this DriverRec be
122  * an upper-case version of the driver name.
123  */
124 
125 _X_EXPORT DriverRec GLINT = {
126     GLINT_VERSION,
127     GLINT_DRIVER_NAME,
128     GLINTIdentify,
129     GLINTProbe,
130     GLINTAvailableOptions,
131     NULL,
132     0
133 };
134 
135 static SymTabRec GLINTVGAChipsets[] = {
136     { PCI_VENDOR_TI_CHIP_PERMEDIA2,		"ti_pm2" },
137     { PCI_VENDOR_TI_CHIP_PERMEDIA,		"ti_pm" },
138     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA4,		"pm4" },
139     { PCI_VENDOR_3DLABS_CHIP_R4,		"r4" },
140     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA3,		"pm3" },
141     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V,	"pm2v" },
142     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2,		"pm2" },
143     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA,		"pm" },
144     {-1, NULL }
145 };
146 
147 static PciChipsets GLINTVGAPciChipsets[] = {
148     { PCI_VENDOR_TI_CHIP_PERMEDIA2,	 PCI_VENDOR_TI_CHIP_PERMEDIA2,	    RES_SHARED_VGA },
149     { PCI_VENDOR_TI_CHIP_PERMEDIA,	 PCI_VENDOR_TI_CHIP_PERMEDIA,	    NULL },
150     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, RES_SHARED_VGA },
151     { PCI_VENDOR_3DLABS_CHIP_R4, PCI_VENDOR_3DLABS_CHIP_R4, RES_SHARED_VGA },
152     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, RES_SHARED_VGA },
153     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, RES_SHARED_VGA },
154     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2,	 PCI_VENDOR_3DLABS_CHIP_PERMEDIA2,  RES_SHARED_VGA },
155     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA,	 PCI_VENDOR_3DLABS_CHIP_PERMEDIA,   NULL },
156     { -1,				 -1,				    RES_UNDEFINED }
157 };
158 
159 static SymTabRec GLINTChipsets[] = {
160     { PCI_VENDOR_3DLABS_CHIP_GAMMA,		"gamma" },
161     { PCI_VENDOR_3DLABS_CHIP_GAMMA2,		"gamma2" },
162     { PCI_VENDOR_TI_CHIP_PERMEDIA2,		"ti_pm2" },
163     { PCI_VENDOR_TI_CHIP_PERMEDIA,		"ti_pm" },
164     { PCI_VENDOR_3DLABS_CHIP_R4,		"r4" },
165     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA4,		"pm4" },
166     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA3,		"pm3" },
167     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V,	"pm2v" },
168     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2,		"pm2" },
169     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA,		"pm" },
170     { PCI_VENDOR_3DLABS_CHIP_300SX,		"300sx" },
171     { PCI_VENDOR_3DLABS_CHIP_500TX,		"500tx" },
172     { PCI_VENDOR_3DLABS_CHIP_MX,		"mx" },
173     { PCI_VENDOR_3DLABS_CHIP_DELTA,		"delta" },
174     { -1,					NULL }
175 };
176 
177 static PciChipsets GLINTPciChipsets[] = {
178     { PCI_VENDOR_3DLABS_CHIP_GAMMA,	 PCI_VENDOR_3DLABS_CHIP_GAMMA,	    NULL },
179     { PCI_VENDOR_3DLABS_CHIP_GAMMA2,	 PCI_VENDOR_3DLABS_CHIP_GAMMA2,	    NULL },
180     { PCI_VENDOR_TI_CHIP_PERMEDIA2,	 PCI_VENDOR_TI_CHIP_PERMEDIA2,	    RES_SHARED_VGA },
181     { PCI_VENDOR_TI_CHIP_PERMEDIA,	 PCI_VENDOR_TI_CHIP_PERMEDIA,	    NULL },
182     { PCI_VENDOR_3DLABS_CHIP_R4, PCI_VENDOR_3DLABS_CHIP_R4, RES_SHARED_VGA },
183     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, PCI_VENDOR_3DLABS_CHIP_PERMEDIA4, RES_SHARED_VGA },
184     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, PCI_VENDOR_3DLABS_CHIP_PERMEDIA3, RES_SHARED_VGA },
185     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, RES_SHARED_VGA },
186     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2,	 PCI_VENDOR_3DLABS_CHIP_PERMEDIA2,  RES_SHARED_VGA },
187     { PCI_VENDOR_3DLABS_CHIP_PERMEDIA,	 PCI_VENDOR_3DLABS_CHIP_PERMEDIA,   NULL },
188     { PCI_VENDOR_3DLABS_CHIP_300SX,	 PCI_VENDOR_3DLABS_CHIP_300SX,	    NULL },
189     { PCI_VENDOR_3DLABS_CHIP_500TX,	 PCI_VENDOR_3DLABS_CHIP_500TX,	    NULL },
190     { PCI_VENDOR_3DLABS_CHIP_MX,	 PCI_VENDOR_3DLABS_CHIP_MX,	    NULL },
191     { PCI_VENDOR_3DLABS_CHIP_DELTA,	 PCI_VENDOR_3DLABS_CHIP_DELTA,	    NULL },
192     { -1,				 -1,				    RES_UNDEFINED }
193 };
194 
195 typedef enum {
196     OPTION_SW_CURSOR,
197     OPTION_RGB_BITS,
198     OPTION_NOACCEL,
199     OPTION_BLOCK_WRITE,
200     OPTION_FIREGL3000,
201     OPTION_OVERLAY,
202     OPTION_SHADOW_FB,
203     OPTION_FBDEV,
204     OPTION_FLATPANEL,
205     OPTION_VIDEO_KEY
206 } GLINTOpts;
207 
208 static const OptionInfoRec GLINTOptions[] = {
209     { OPTION_SW_CURSOR,		"SWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
210     { OPTION_RGB_BITS,		"RGBbits",	OPTV_INTEGER,	{0}, FALSE },
211     { OPTION_NOACCEL,		"NoAccel",	OPTV_BOOLEAN,	{0}, FALSE },
212     { OPTION_BLOCK_WRITE,	"BlockWrite",	OPTV_BOOLEAN,   {0}, FALSE },
213     { OPTION_FIREGL3000,	"FireGL3000",   OPTV_BOOLEAN,	{0}, FALSE },
214     { OPTION_OVERLAY,		"Overlay",	OPTV_ANYSTR,	{0}, FALSE },
215     { OPTION_SHADOW_FB,		"ShadowFB",	OPTV_BOOLEAN,	{0}, FALSE },
216     { OPTION_FBDEV,		"UseFBDev",	OPTV_BOOLEAN,	{0}, FALSE },
217     { OPTION_FLATPANEL,		"UseFlatPanel",	OPTV_BOOLEAN,	{0}, FALSE },
218     { OPTION_VIDEO_KEY,		"VideoKey",	OPTV_BOOLEAN,	{0}, FALSE },
219     { -1,			NULL,		OPTV_NONE,	{0}, FALSE }
220 };
221 
222 static RamDacSupportedInfoRec IBMRamdacs[] = {
223     { IBM526DB_RAMDAC },
224     { IBM526_RAMDAC },
225     { IBM640_RAMDAC },
226     { -1 }
227 };
228 
229 static RamDacSupportedInfoRec TIRamdacs[] = {
230     { TI3030_RAMDAC },
231     { TI3026_RAMDAC },
232     { -1 }
233 };
234 
235 static MODULESETUPPROTO(glintSetup);
236 
237 static XF86ModuleVersionInfo glintVersRec =
238 {
239 	"glint",
240 	MODULEVENDORSTRING,
241 	MODINFOSTRING1,
242 	MODINFOSTRING2,
243 	XORG_VERSION_CURRENT,
244 	GLINT_MAJOR_VERSION, GLINT_MINOR_VERSION, GLINT_PATCHLEVEL,
245 	ABI_CLASS_VIDEODRV,			/* This is a video driver */
246 	ABI_VIDEODRV_VERSION,
247 	MOD_CLASS_VIDEODRV,
248 	{0,0,0,0}
249 };
250 
251 _X_EXPORT XF86ModuleData glintModuleData = { &glintVersRec, glintSetup, NULL };
252 
253 pointer
glintSetup(pointer module,pointer opts,int * errmaj,int * errmin)254 glintSetup(pointer module, pointer opts, int *errmaj, int *errmin)
255 {
256     static Bool setupDone = FALSE;
257 
258     if (!setupDone) {
259 	setupDone = TRUE;
260 	xf86AddDriver(&GLINT, module, 0);
261 	return (pointer)TRUE;
262     }
263 
264     if (errmaj) *errmaj = LDR_ONCEONLY;
265     return NULL;
266 }
267 
268 #define PARTPROD(a,b,c) (((a)<<6) | ((b)<<3) | (c))
269 
270 static char bppand[4] = { 0x03, /* 8bpp */
271 			  0x01, /* 16bpp */
272 			  0x00, /* 24bpp */
273 			  0x00  /* 32bpp */};
274 
275 static int partprod500TX[] = {
276 	-1,
277 	PARTPROD(0,0,1), PARTPROD(0,0,2), PARTPROD(0,1,2), PARTPROD(0,0,3),
278 	PARTPROD(0,1,3), PARTPROD(0,2,3), PARTPROD(1,2,3), PARTPROD(0,0,4),
279 	PARTPROD(0,1,4), PARTPROD(0,2,4), PARTPROD(1,2,4), PARTPROD(0,3,4),
280 	PARTPROD(1,3,4), PARTPROD(2,3,4),              -1, PARTPROD(0,0,5),
281 	PARTPROD(0,1,5), PARTPROD(0,2,5), PARTPROD(1,2,5), PARTPROD(0,3,5),
282 	PARTPROD(1,3,5), PARTPROD(2,3,5),              -1, PARTPROD(0,4,5),
283 	PARTPROD(1,4,5), PARTPROD(2,4,5), PARTPROD(3,4,5),              -1,
284 	             -1,              -1,              -1, PARTPROD(0,0,6),
285 	PARTPROD(0,1,6), PARTPROD(0,2,6), PARTPROD(1,2,6), PARTPROD(0,3,6),
286 	PARTPROD(1,3,6), PARTPROD(2,3,6),              -1, PARTPROD(0,4,6),
287 	PARTPROD(1,4,6), PARTPROD(2,4,6),              -1, PARTPROD(3,4,6),
288 	             -1,              -1,              -1, PARTPROD(0,5,6),
289 	PARTPROD(1,5,6), PARTPROD(2,5,6),              -1, PARTPROD(3,5,6),
290 	             -1,              -1,              -1, PARTPROD(4,5,6),
291 	             -1,              -1,              -1,              -1,
292 		     -1,              -1,              -1, PARTPROD(0,0,7),
293 	             -1, PARTPROD(0,2,7), PARTPROD(1,2,7), PARTPROD(0,3,7),
294 	PARTPROD(1,3,7), PARTPROD(2,3,7),              -1, PARTPROD(0,4,7),
295 	PARTPROD(1,4,7), PARTPROD(2,4,7),              -1, PARTPROD(3,4,7),
296 	             -1,              -1,              -1, PARTPROD(0,5,7),
297 	PARTPROD(1,5,7), PARTPROD(2,5,7),              -1, PARTPROD(3,5,7),
298 	             -1,              -1,              -1, PARTPROD(4,5,7),
299 	             -1,              -1,              -1,              -1,
300 		     -1,              -1,              -1, PARTPROD(0,6,7),
301 	PARTPROD(1,6,7), PARTPROD(2,6,7),              -1, PARTPROD(3,6,7),
302 	             -1,              -1,              -1, PARTPROD(4,6,7),
303 	             -1,              -1,              -1,              -1,
304 		     -1,              -1,              -1, PARTPROD(5,6,7),
305 	             -1,              -1,              -1,              -1,
306 		     -1,              -1,              -1,              -1,
307 		     -1,              -1,              -1,              -1,
308 		     -1,              -1,              -1, PARTPROD(0,7,7),
309 		      0};
310 
311 int partprodPermedia[] = {
312 	-1,
313 	PARTPROD(0,0,1), PARTPROD(0,1,1), PARTPROD(1,1,1), PARTPROD(1,1,2),
314 	PARTPROD(1,2,2), PARTPROD(2,2,2), PARTPROD(1,2,3), PARTPROD(2,2,3),
315 	PARTPROD(1,3,3), PARTPROD(2,3,3), PARTPROD(1,2,4), PARTPROD(3,3,3),
316 	PARTPROD(1,3,4), PARTPROD(2,3,4),              -1, PARTPROD(3,3,4),
317 	PARTPROD(1,4,4), PARTPROD(2,4,4),              -1, PARTPROD(3,4,4),
318 	             -1, PARTPROD(2,3,5),              -1, PARTPROD(4,4,4),
319 	PARTPROD(1,4,5), PARTPROD(2,4,5), PARTPROD(3,4,5),              -1,
320 	             -1,              -1,              -1, PARTPROD(4,4,5),
321 	PARTPROD(1,5,5), PARTPROD(2,5,5),              -1, PARTPROD(3,5,5),
322 	             -1,              -1,              -1, PARTPROD(4,5,5),
323 	             -1,              -1,              -1, PARTPROD(3,4,6),
324 	             -1,              -1,              -1, PARTPROD(5,5,5),
325 	PARTPROD(1,5,6), PARTPROD(2,5,6),              -1, PARTPROD(3,5,6),
326 	             -1,              -1,              -1, PARTPROD(4,5,6),
327 	             -1,              -1,              -1,              -1,
328 	             -1,              -1,              -1, PARTPROD(5,5,6),
329 	             -1,              -1,              -1,              -1,
330 	             -1,              -1,              -1,              -1,
331 	             -1,              -1,              -1,              -1,
332 	             -1,              -1,              -1,              -1,
333 	             -1,              -1,              -1,              -1,
334 	             -1,              -1,              -1,              -1,
335 	             -1,              -1,              -1,              -1,
336 	             -1,              -1,              -1,              -1,
337 	             -1,              -1,              -1,              -1,
338 	             -1,              -1,              -1,              -1,
339 	             -1,              -1,              -1,              -1,
340 	             -1,              -1,              -1,              -1,
341 	             -1,              -1,              -1,              -1,
342 	             -1,              -1,              -1,              -1,
343 	             -1,              -1,              -1,              -1,
344 	             -1,              -1,              -1,              -1,
345 		     0};
346 
347 static void
GLINTDisplayPowerManagementSet(ScrnInfoPtr pScrn,int PowerManagementMode,int flags)348 GLINTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
349 					int flags)
350 {
351     GLINTPtr pGlint = GLINTPTR(pScrn);
352     int videocontrol = 0, vtgpolarity = 0;
353 
354     if((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX) ||
355        (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_300SX) ||
356        (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) ||
357        ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
358         (pGlint->MultiChip == PCI_CHIP_3DLABS_300SX)) ||
359        ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
360         (pGlint->MultiChip == PCI_CHIP_3DLABS_500TX)) ||
361        ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
362         (pGlint->MultiChip == PCI_CHIP_3DLABS_MX)) ||
363        ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
364         (pGlint->MultiChip == PCI_CHIP_3DLABS_MX)) ) {
365 	vtgpolarity = GLINT_READ_REG(VTGPolarity) & 0xFFFFFFF0;
366     } else {
367         videocontrol = GLINT_READ_REG(PMVideoControl) & 0xFFFFFFD6;
368     }
369 
370     switch (PowerManagementMode) {
371 	case DPMSModeOn:
372 	    /* Screen: On, HSync: On, VSync: On */
373 	    videocontrol |= 0x29;
374 	    vtgpolarity |= 0x05;
375 	    break;
376 	case DPMSModeStandby:
377 	    /* Screen: Off, HSync: Off, VSync: On */
378 	    videocontrol |= 0x20;
379 	    vtgpolarity |= 0x04;
380 	    break;
381 	case DPMSModeSuspend:
382 	    /* Screen: Off, HSync: On, VSync: Off */
383 	    videocontrol |= 0x08;
384 	    vtgpolarity |= 0x01;
385 	    break;
386 	case DPMSModeOff:
387 	    /* Screen: Off, HSync: Off, VSync: Off */
388 	    videocontrol |= 0x00;
389 	    vtgpolarity |= 0x00;
390 	    break;
391 	default:
392 	    return;
393     }
394 
395     if((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX) ||
396        (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_300SX) ||
397        (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) ||
398        ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
399         (pGlint->MultiChip == PCI_CHIP_3DLABS_300SX)) ||
400        ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
401         (pGlint->MultiChip == PCI_CHIP_3DLABS_500TX)) ||
402        ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
403         (pGlint->MultiChip == PCI_CHIP_3DLABS_MX)) ||
404        ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
405         (pGlint->MultiChip == PCI_CHIP_3DLABS_MX)) ) {
406     	GLINT_SLOW_WRITE_REG(vtgpolarity, VTGPolarity);
407     } else {
408     	GLINT_SLOW_WRITE_REG(videocontrol, PMVideoControl);
409     }
410 }
411 
412 static Bool
GLINTGetRec(ScrnInfoPtr pScrn)413 GLINTGetRec(ScrnInfoPtr pScrn)
414 {
415     TRACE_ENTER("GLINTGetRec");
416     /*
417      * Allocate an GLINTRec, and hook it into pScrn->driverPrivate.
418      * pScrn->driverPrivate is initialised to NULL, so we can check if
419      * the allocation has already been done.
420      */
421     if (pScrn->driverPrivate != NULL)
422 	return TRUE;
423 
424     pScrn->driverPrivate = xnfcalloc(sizeof(GLINTRec), 1);
425     /* Initialise it */
426 
427     TRACE_EXIT("GLINTGetRec");
428     return TRUE;
429 }
430 
431 static void
GLINTFreeRec(ScrnInfoPtr pScrn)432 GLINTFreeRec(ScrnInfoPtr pScrn)
433 {
434     TRACE_ENTER("GLINTFreeRec");
435     if (pScrn->driverPrivate == NULL)
436 	return;
437     free(pScrn->driverPrivate);
438     pScrn->driverPrivate = NULL;
439     TRACE_EXIT("GLINTFreeRec");
440 }
441 
442 
443 /* Mandatory */
444 static void
GLINTIdentify(int flags)445 GLINTIdentify(int flags)
446 {
447     xf86PrintChipsets(GLINT_NAME, "driver for 3Dlabs chipsets", GLINTChipsets);
448 }
449 
450 static const OptionInfoRec *
GLINTAvailableOptions(int chipid,int busid)451 GLINTAvailableOptions(int chipid, int busid)
452 {
453     return GLINTOptions;
454 }
455 
456 static void
GLINTProbeDDC(ScrnInfoPtr pScrn,int index)457 GLINTProbeDDC(ScrnInfoPtr pScrn, int index)
458 {
459     vbeInfoPtr pVbe;
460     if (xf86LoadSubModule(pScrn, "vbe"))
461     {
462 	pVbe =  VBEInit(NULL,index);
463 	vbeDoEDID(pVbe, NULL);
464 	vbeFree(pVbe);
465     }
466 }
467 
468 /* Mandatory */
469 static Bool
GLINTProbe(DriverPtr drv,int flags)470 GLINTProbe(DriverPtr drv, int flags)
471 {
472     int i;
473     pciVideoPtr pPci, *checkusedPci;
474     GDevPtr *devSections;
475     int numDevSections;
476     int numUsed,bus,device,func;
477     char *dev;
478     int *usedChips = NULL;
479     Bool foundScreen = FALSE;
480     char *name;
481 
482     /*
483     TRACE_ENTER("GLINTProbe");
484     */
485     TRACE_EXIT("GLINTProbe (Enter)");
486 
487 
488     if ((numDevSections = xf86MatchDevice(GLINT_DRIVER_NAME,
489   					  &devSections)) <= 0) {
490   	return FALSE;
491     }
492 
493 #ifndef XSERVER_LIBPCIACCESS
494     checkusedPci = xf86GetPciVideoInfo();
495 
496     if (checkusedPci == NULL && devSections /* for xf86DoProbe */)
497       {
498   	/*
499  	 * Changed the behaviour to try probing using the FBDev support
500  	 * when no PCI cards have been found. This is for systems without
501  	 * (proper) PCI support. (Michel)
502   	 */
503  	if (!xf86LoadDrvSubModule(drv, "fbdevhw"))
504 	    return FALSE;
505 
506  	for (i = 0; i < numDevSections; i++) {
507  	    dev = xf86FindOptionValue(devSections[i]->options,"fbdev");
508  	    if (devSections[i]->busID) {
509  		xf86ParsePciBusString(devSections[i]->busID,&bus,&device,&func);
510  		if (!xf86CheckPciSlot(bus,device,func))
511  		    continue;
512  	    }
513  	    if (fbdevHWProbe(NULL,dev,&name)) {
514  		ScrnInfoPtr pScrn;
515 
516   				/* Check for pm2fb */
517  		if (strcmp(name,"Permedia2")) continue;
518  		foundScreen = TRUE;
519  		pScrn = NULL;
520 
521  		if (devSections[i]->busID) {
522  		    /* XXX what about when there's no busID set? */
523  		    int entity;
524  		    entity = xf86ClaimPciSlot(bus,device,func,drv,
525  					      0,devSections[i],
526  					      TRUE);
527  		    pScrn = xf86ConfigPciEntity(pScrn,0,entity,
528  						      NULL,RES_SHARED_VGA,
529  						      NULL,NULL,NULL,NULL);
530  		    if (pScrn)
531   			xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
532   				   "claimed PCI slot %d:%d:%d\n",bus,device,func);
533  		}
534 		if (pScrn) {
535   		    /* Fill in what we can of the ScrnInfoRec */
536  		    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
537  			       "%s successfully probed\n", dev ? dev : "default framebuffer device");
538   		    pScrn->driverVersion = GLINT_VERSION;
539   		    pScrn->driverName	 = GLINT_DRIVER_NAME;
540 		    pScrn->name		 = GLINT_NAME;
541 		    pScrn->Probe	 = GLINTProbe;
542 		    pScrn->PreInit	 = GLINTPreInit;
543 		    pScrn->ScreenInit	 = GLINTScreenInit;
544 		    pScrn->SwitchMode	 = GLINTSwitchMode;
545 		    pScrn->FreeScreen	 = GLINTFreeScreen;
546 		    pScrn->EnterVT	 = GLINTEnterVT;
547 		}
548 	    }
549 	}
550 
551     	free(devSections);
552 
553     } else  if (checkusedPci)
554 #endif
555 {
556 	if (flags & PROBE_DETECT) {
557 	   /* HACK, Currently when -configuring, we only return VGA
558 	    * based chips. Manual configuring is necessary to poke
559 	    * at the other chips */
560 	   numUsed = xf86MatchPciInstances(GLINT_NAME, 0,
561 				GLINTVGAChipsets, GLINTVGAPciChipsets,
562 				devSections,
563 				numDevSections, drv, &usedChips);
564 	} else {
565 	   numUsed = xf86MatchPciInstances(GLINT_NAME, 0,
566 				GLINTChipsets, GLINTPciChipsets, devSections,
567 				numDevSections, drv, &usedChips);
568 	}
569 
570 	free(devSections);
571 	if (numUsed <= 0)
572 	    return FALSE;
573 	foundScreen = TRUE;
574 
575 	if (!(flags & PROBE_DETECT))
576 	    for (i = 0; i < numUsed; i++) {
577 		ScrnInfoPtr pScrn = NULL;
578 		GLINTEntPtr pGlintEnt = NULL;
579 		DevUnion *pPriv;
580 
581 		pPci = xf86GetPciInfoForEntity(usedChips[i]);
582 		/* Allocate a ScrnInfoRec and claim the slot */
583 		if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
584 					       GLINTPciChipsets, NULL,
585 					       NULL, NULL, NULL, NULL))) {
586 
587 
588 		/* Claim specifics, when we KNOW ! the board */
589 #ifndef XSERVER_LIBPCIACCESS
590 		/* Appian Jeronimo J2000 */
591 		if ((PCI_SUB_VENDOR_ID(pPci) == 0x1097) &&
592 	    	    (PCI_SUB_DEVICE_ID(pPci)   == 0x3d32)) {
593 			int eIndex;
594 			int init_func;
595 
596 			if (!xf86IsEntityShared(usedChips[i])) {
597 		    	eIndex = xf86ClaimPciSlot(pPci->bus,
598 						  pPci->device,
599 						  1,
600 						  drv, -1 /* XXX */,
601 						  NULL, FALSE);
602 		    	xf86AddEntityToScreen(pScrn,eIndex);
603 			} else {
604 		    	eIndex = xf86ClaimPciSlot(pPci->bus,
605 						  pPci->device,
606 						  2,
607 						  drv, -1 /* XXX */,
608 						  NULL, FALSE);
609 		    	xf86AddEntityToScreen(pScrn,eIndex);
610 			}
611 		} else
612     		/* Only claim other chips when GAMMA is used */
613     		if ((PCI_DEV_DEVICE_ID(pPci) ==  PCI_CHIP_3DLABS_GAMMA) ||
614 		    (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_3DLABS_GAMMA2) ||
615 		    (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_3DLABS_DELTA)) {
616 		    while (*checkusedPci != NULL) {
617 	    	    	int eIndex;
618 	    	    	/* make sure we claim all but our source device */
619 	    	    	if ((pPci->bus ==    PCI_DEV_BUS(*checkusedPci) &&
620 	         	     pPci->device == PCI_DEV_DEV((*checkusedPci)) &&
621 	         	     pPci->func !=   PCI_DEV_FUNC(*checkusedPci))) {
622 
623 		    	/* Claim other entities on the same card */
624 		    	eIndex = xf86ClaimPciSlot((*checkusedPci)->bus,
625 						  (*checkusedPci)->device,
626 						  (*checkusedPci)->func,
627 						  drv, -1 /* XXX */,
628 						  NULL, FALSE);
629 
630 		    	if (eIndex != -1) {
631 		    	    xf86AddEntityToScreen(pScrn,eIndex);
632 		    	} else {
633 		    	    ErrorF("BusID %d:%d:%d already claimed\n",
634 				   PCI_DEV_BUS(*checkusedPci),
635 				   PCI_DEV_DEV(*checkusedPci),
636 				   PCI_DEV_FUNC(*checkusedPci));
637     		    	    free(usedChips);
638 		    	    return FALSE;
639 		        }
640 	                }
641 	                checkusedPci++;
642 	            }
643 		}
644 #endif
645 
646 		/* Fill in what we can of the ScrnInfoRec */
647 		pScrn->driverVersion	= GLINT_VERSION;
648 		pScrn->driverName	= GLINT_DRIVER_NAME;
649 		pScrn->name		= GLINT_NAME;
650 		pScrn->Probe	 	= GLINTProbe;
651 		pScrn->PreInit	 	= GLINTPreInit;
652 		pScrn->ScreenInit	= GLINTScreenInit;
653 		pScrn->SwitchMode	= GLINTSwitchMode;
654 		pScrn->FreeScreen	= GLINTFreeScreen;
655 		pScrn->EnterVT		= GLINTEnterVT;
656 		}
657 
658 		/* Allow sharing if Appian J2000 detected */
659 		/* (later Diamond FireGL3000 support too) */
660 
661 		if ((PCI_SUB_VENDOR_ID(pPci) == 0x1097) &&
662 	    	    (PCI_SUB_DEVICE_ID(pPci) == 0x3d32)) {
663 	    	    xf86SetEntitySharable(usedChips[i]);
664 	    	    /* Allocate an entity private if necessary */
665 	    	    if (GLINTEntityIndex < 0)
666 			GLINTEntityIndex = xf86AllocateEntityPrivateIndex();
667 	    	    pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
668 							GLINTEntityIndex);
669 	    	    if (!pPriv->ptr) {
670 			pPriv->ptr = xnfcalloc(sizeof(GLINTEntRec), 1);
671 			pGlintEnt = pPriv->ptr;
672 			pGlintEnt->lastInstance = -1;
673 	    	    } else {
674 			pGlintEnt = pPriv->ptr;
675 	    	    }
676 
677 	    	    /*
678 	     	     * Set the entity instance for this instance of the driver.
679 	     	     * For dual head per card, instance 0 is the "master"
680 	     	     * instance, driving the primary head, and instance 1 is
681 	     	     * the "slave".
682 	     	     */
683 	    	    pGlintEnt->lastInstance++;
684 	            xf86SetEntityInstanceForScreen(pScrn,
685 				pScrn->entityList[0], pGlintEnt->lastInstance);
686 		}
687 	}
688     }
689 
690     free(usedChips);
691 
692     TRACE_EXIT("GLINTProbe");
693     return foundScreen;
694 }
695 
696 /*
697  * GetAccelPitchValues -
698  *
699  * This function returns a list of display width (pitch) values that can
700  * be used in accelerated mode.
701  */
702 static int *
GetAccelPitchValues(ScrnInfoPtr pScrn)703 GetAccelPitchValues(ScrnInfoPtr pScrn)
704 {
705     int *linePitches = NULL;
706     int i, n = 0;
707     int *linep = NULL;
708     GLINTPtr pGlint = GLINTPTR(pScrn);
709 
710     switch (pGlint->Chipset) {
711     case PCI_VENDOR_TI_CHIP_PERMEDIA2:
712     case PCI_VENDOR_TI_CHIP_PERMEDIA:
713     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
714     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
715     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
716 	linep = &partprodPermedia[0];
717 	break;
718     case PCI_VENDOR_3DLABS_CHIP_500TX:
719     case PCI_VENDOR_3DLABS_CHIP_300SX:
720     case PCI_VENDOR_3DLABS_CHIP_MX:
721 	linep = &partprod500TX[0];
722 	break;
723     case PCI_VENDOR_3DLABS_CHIP_GAMMA:
724     case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
725     case PCI_VENDOR_3DLABS_CHIP_DELTA:
726 	/* When GAMMA/DELTA in use, we always have MultiChip defined, even if
727 	 * only one chip is connected to GAMMA/DELTA as the entities > 1
728 	 */
729     	switch (pGlint->MultiChip) {
730 	case PCI_CHIP_3DLABS_MX:
731 	case PCI_CHIP_3DLABS_500TX:
732 	case PCI_CHIP_3DLABS_300SX:
733 	    linep = &partprod500TX[0];
734 	    break;
735 	case PCI_CHIP_3DLABS_PERMEDIA:
736 	case PCI_CHIP_TI_PERMEDIA:
737 	    linep = &partprodPermedia[0];
738 	    break;
739 	}
740 	break;
741     }
742 
743     for (i = 0; linep[i] != 0; i++) {
744 	if (linep[i] != -1) {
745 	    n++;
746 	    linePitches = xnfrealloc(linePitches, n * sizeof(int));
747 	    linePitches[n - 1] = i << 5;
748 	}
749     }
750 
751     /* Mark the end of the list */
752     if (n > 0) {
753 	linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
754 	linePitches[n] = 0;
755     }
756 
757     return linePitches;
758 }
759 
760 static void
GLINTProbeTIramdac(ScrnInfoPtr pScrn)761 GLINTProbeTIramdac(ScrnInfoPtr pScrn)
762 {
763     GLINTPtr pGlint;
764     CARD32 temp = 0;
765     pGlint = GLINTPTR(pScrn);
766 
767     pGlint->RamDacRec = RamDacCreateInfoRec();
768     pGlint->RamDacRec->ReadDAC = glintInTIIndReg;
769     pGlint->RamDacRec->WriteDAC = glintOutTIIndReg;
770     pGlint->RamDacRec->ReadAddress = glintTIReadAddress;
771     pGlint->RamDacRec->WriteAddress = glintTIWriteAddress;
772     pGlint->RamDacRec->ReadData = glintTIReadData;
773     pGlint->RamDacRec->WriteData = glintTIWriteData;
774     pGlint->RamDacRec->LoadPalette = TIramdacLoadPaletteWeak();
775 
776     if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
777 	RamDacDestroyInfoRec(pGlint->RamDacRec);
778 	return;
779     }
780     GLINTMapMem(pScrn);
781     if (pGlint->numMultiDevices == 2) {
782     	temp = GLINT_READ_REG(GCSRAperture);
783     	GLINT_SLOW_WRITE_REG(GCSRSecondaryGLINTMapEn, GCSRAperture);
784     }
785     pGlint->RamDac = TIramdacProbe(pScrn, TIRamdacs);
786     if (pGlint->numMultiDevices == 2) {
787     	GLINT_SLOW_WRITE_REG(temp, GCSRAperture);
788     }
789     GLINTUnmapMem(pScrn);
790 }
791 
792 static void
GLINTProbeIBMramdac(ScrnInfoPtr pScrn)793 GLINTProbeIBMramdac(ScrnInfoPtr pScrn)
794 {
795     GLINTPtr pGlint;
796     pGlint = GLINTPTR(pScrn);
797     pGlint->RamDacRec = RamDacCreateInfoRec();
798     pGlint->RamDacRec->ReadDAC = glintInIBMRGBIndReg;
799     pGlint->RamDacRec->WriteDAC = glintOutIBMRGBIndReg;
800     pGlint->RamDacRec->ReadAddress = glintIBMReadAddress;
801     pGlint->RamDacRec->WriteAddress = glintIBMWriteAddress;
802     pGlint->RamDacRec->ReadData = glintIBMReadData;
803     pGlint->RamDacRec->WriteData = glintIBMWriteData;
804     pGlint->RamDacRec->LoadPalette = NULL;
805     if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
806 	RamDacDestroyInfoRec(pGlint->RamDacRec);
807 	return;
808     }
809     GLINTMapMem(pScrn);
810     pGlint->RamDac = IBMramdacProbe(pScrn, IBMRamdacs);
811     GLINTUnmapMem(pScrn);
812 }
813 
814 /* Mandatory */
815 static Bool
GLINTPreInit(ScrnInfoPtr pScrn,int flags)816 GLINTPreInit(ScrnInfoPtr pScrn, int flags)
817 {
818     GLINTPtr pGlint;
819     GLINTEntPtr pGlintEnt = NULL;
820     MessageType from;
821     int i;
822     Bool Overlay = FALSE;
823     int maxwidth = 0, maxheight = 0;
824     ClockRangePtr clockRanges;
825     char *mod = NULL;
826     const char *s;
827 
828     TRACE_ENTER("GLINTPreInit");
829 
830     /*
831      * Note: This function is only called once at server startup, and
832      * not at the start of each server generation.  This means that
833      * only things that are persistent across server generations can
834      * be initialised here.  xf86Screens[] is (pScrn is a pointer to one
835      * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()
836      * are too, and should be used for data that must persist across
837      * server generations.
838      *
839      * Per-generation data should be allocated with
840      * AllocateScreenPrivateIndex() from the ScreenInit() function.
841      */
842 
843     /* Check the number of entities, and fail if it isn't one or more. */
844     if (pScrn->numEntities < 1)
845 	return FALSE;
846 
847     /* Allocate the GLINTRec driverPrivate */
848     if (!GLINTGetRec(pScrn)) {
849 	return FALSE;
850     }
851     pGlint = GLINTPTR(pScrn);
852 
853     /* Get the entities, and make sure they are PCI. */
854     pGlint->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
855 
856     /* Allocate an entity private if necessary */
857     if (xf86IsEntityShared(pScrn->entityList[0])) {
858 	pGlintEnt = xf86GetEntityPrivate(pScrn->entityList[0],
859 					GLINTEntityIndex)->ptr;
860         pGlint->entityPrivate = pGlintEnt;
861     }
862 
863     if (pGlint->pEnt->location.type == BUS_PCI)
864     {
865         pGlint->PciInfo = xf86GetPciInfoForEntity(pGlint->pEnt->index);
866 #ifndef XSERVER_LIBPCIACCESS
867         pGlint->PciTag = pciTag(pGlint->PciInfo->bus, pGlint->PciInfo->device,
868 			    pGlint->PciInfo->func);
869 #endif
870     }
871 
872     pGlint->InFifoSpace = 0;	/* Force a Read of FIFO space on first run */
873     pGlint->numMultiDevices = 0;
874     pGlint->IOOffset = 0;	/* Set IO Offset for Gamma */
875 
876     if (pScrn->numEntities > 1) {
877 	pciVideoPtr pPci;
878 	EntityInfoPtr pEnt;
879 
880 	for (i = 1; i < pScrn->numEntities; i++) {
881 	    pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
882 	    pPci = xf86GetPciInfoForEntity(pEnt->index);
883 	    if ( (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_3DLABS_MX) ||
884 		 (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_3DLABS_PERMEDIA) ||
885 		 (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_TI_PERMEDIA) ||
886 		 (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_3DLABS_500TX) ||
887 		 (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_3DLABS_300SX) ||
888 		 (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_3DLABS_R4) ||
889 		 (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_3DLABS_PERMEDIA3) ) {
890 		pGlint->MultiChip = PCI_DEV_DEVICE_ID(pPci);
891 		if (pGlint->numMultiDevices >= GLINT_MAX_MULTI_DEVICES) {
892 		    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
893 			"%d multiple chips unsupported, aborting. (Max - 2)\n",
894 			pGlint->numMultiDevices);
895 		    return FALSE;
896 		} else {
897 		    pGlint->MultiPciInfo[pGlint->numMultiDevices] = pPci;
898 		    pGlint->numMultiDevices++;
899 		}
900 	    }
901 	}
902     }
903 
904     {
905 	EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
906 	pciVideoPtr pPci = xf86GetPciInfoForEntity(pEnt->index);
907 
908         if ( ((PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_3DLABS_GAMMA) ||
909 	      (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_3DLABS_GAMMA2) ||
910 	      (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_3DLABS_DELTA)) &&
911              (pGlint->numMultiDevices == 0) ) {
912 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
913 			"Gamma/Delta with ZERO connected chips, aborting\n");
914 	    return FALSE;
915         }
916     }
917 
918     if (flags & PROBE_DETECT) {
919 	EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
920 	pciVideoPtr pPci = xf86GetPciInfoForEntity(pEnt->index);
921 
922         if ((PCI_DEV_DEVICE_ID(pPci) != PCI_CHIP_3DLABS_GAMMA) &&
923 	    (PCI_DEV_DEVICE_ID(pPci) != PCI_CHIP_3DLABS_GAMMA2) &&
924 	    (PCI_DEV_DEVICE_ID(pPci) != PCI_CHIP_3DLABS_DELTA)) {
925 	    GLINTProbeDDC(pScrn, pGlint->pEnt->index);
926 	    return TRUE;
927 	} else
928 	    return FALSE;
929     }
930 
931 #ifndef XSERVER_LIBPCIACCESS
932     xf86SetOperatingState(resVga, pGlint->pEnt->index, ResDisableOpr);
933 
934     /* Operations for which memory access is required. */
935     pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
936     pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
937 #endif
938     /* Set pScrn->monitor */
939     pScrn->monitor = pScrn->confScreen->monitor;
940     /*
941      * The first thing we should figure out is the depth, bpp, etc.
942      * We support both 24bpp and 32bpp layouts, so indicate that.
943      */
944     if (FBDevProbed) {
945 	int default_depth, fbbpp;
946 
947 	if (!fbdevHWInit(pScrn, pGlint->PciInfo,
948 			 xf86FindOptionValue(pGlint->pEnt->device->options,
949 					     "fbdev"))) {
950 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "fbdevHWInit failed!\n");
951 		return FALSE;
952 	}
953 	default_depth = fbdevHWGetDepth(pScrn,&fbbpp);
954 	if (!xf86SetDepthBpp(pScrn, default_depth, default_depth, fbbpp,0))
955 		return FALSE;
956     } else {
957 	if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb
958 	 	/*| SupportConvert32to24 | PreferConvert32to24*/))
959 		return FALSE;
960     }
961     /* Check that the returned depth is one we support */
962     switch (pScrn->depth) {
963     case 8:
964     case 15:
965     case 16:
966     case 24:
967     case 30:
968 	/* OK */
969 	break;
970     default:
971 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
972 		"Given depth (%d) is not supported by this driver\n",
973 		pScrn->depth);
974 	return FALSE;
975     }
976 
977     xf86PrintDepthBpp(pScrn);
978 
979     /*
980      * This must happen after pScrn->display has been set because
981      * xf86SetWeight references it.
982      */
983     if (pScrn->depth > 8) {
984 	/* The defaults are OK for us */
985 	rgb zeros = {0, 0, 0};
986 
987 	if (!xf86SetWeight(pScrn, zeros, zeros)) {
988 	    return FALSE;
989 	} else {
990 	    /* XXX check that weight returned is supported */
991             ;
992         }
993     }
994 
995     if (!xf86SetDefaultVisual(pScrn, -1)) {
996 	return FALSE;
997     } else {
998 	/* We don't currently support DirectColor at > 8bpp */
999 	if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
1000 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
1001 		       " (%s) is not supported at depth %d\n",
1002 		       xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
1003 	    return FALSE;
1004 	}
1005     }
1006 
1007     /*
1008      * If the driver can do gamma correction, it should call xf86SetGamma()
1009      * here.
1010      */
1011 
1012     {
1013 	Gamma zeros = {0.0, 0.0, 0.0};
1014 
1015 	if (!xf86SetGamma(pScrn, zeros)) {
1016 	    return FALSE;
1017 	}
1018     }
1019 
1020     /* We use a programmable clock */
1021     pScrn->progClock = TRUE;
1022 
1023     /* Collect all of the relevant option flags (fill in pScrn->options) */
1024     xf86CollectOptions(pScrn, NULL);
1025 
1026     /* Process the options */
1027     if (!(pGlint->Options = malloc(sizeof(GLINTOptions))))
1028 	return FALSE;
1029     memcpy(pGlint->Options, GLINTOptions, sizeof(GLINTOptions));
1030     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pGlint->Options);
1031 
1032     /* Default to 8bits per RGB */
1033     if (pScrn->depth == 30)  pScrn->rgbBits = 10;
1034     else pScrn->rgbBits = 8;
1035     if (xf86GetOptValInteger(pGlint->Options, OPTION_RGB_BITS, &pScrn->rgbBits)) {
1036 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
1037 		       pScrn->rgbBits);
1038     }
1039 
1040     from = X_DEFAULT;
1041     pGlint->HWCursor = TRUE; /* ON by default */
1042     if (xf86ReturnOptValBool(pGlint->Options, OPTION_SW_CURSOR, FALSE)) {
1043 	from = X_CONFIG;
1044 	pGlint->HWCursor = FALSE;
1045     }
1046     xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
1047 		pGlint->HWCursor ? "HW" : "SW");
1048     if (xf86ReturnOptValBool(pGlint->Options, OPTION_FLATPANEL, FALSE)) {
1049 	pGlint->UseFlatPanel = TRUE;
1050         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using Flat Panel Interface\n");
1051     }
1052     if (xf86ReturnOptValBool(pGlint->Options, OPTION_NOACCEL, FALSE)) {
1053 	pGlint->NoAccel = TRUE;
1054 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
1055     }
1056     if (xf86ReturnOptValBool(pGlint->Options, OPTION_SHADOW_FB, FALSE)) {
1057 	pGlint->ShadowFB = TRUE;
1058 	pGlint->NoAccel = TRUE;
1059 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1060 		"Using \"Shadow Framebuffer\" - acceleration disabled\n");
1061     }
1062     if(xf86GetOptValInteger(pGlint->Options, OPTION_VIDEO_KEY,
1063 						&(pGlint->videoKey))) {
1064 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
1065 							pGlint->videoKey);
1066     } else {
1067 	/* Needs 8bit values for all modes */
1068 	pGlint->videoKey =  (1 << 16) |
1069 			    (1 << 8) |
1070 			    ((pScrn->mask.blue - 1) << 0);
1071     }
1072 
1073     /* Check whether to use the FBDev stuff and fill in the rest of pScrn */
1074     if (xf86ReturnOptValBool(pGlint->Options, OPTION_FBDEV, FALSE)) {
1075     	if (!FBDevProbed && !xf86LoadSubModule(pScrn, "fbdevhw"))
1076     	{
1077 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "couldn't load fbdevHW module!\n");
1078 		return FALSE;
1079 	}
1080 
1081 	if (!fbdevHWInit(pScrn, pGlint->PciInfo,
1082 			 xf86FindOptionValue(pGlint->pEnt->device->options,
1083 					     "fbdev")))
1084 	{
1085 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "fbdevHWInit failed!\n");
1086 		return FALSE;
1087 	}
1088 
1089 	pGlint->FBDev = TRUE;
1090         from = X_CONFIG;
1091 
1092 	pScrn->AdjustFrame	= fbdevHWAdjustFrameWeak();
1093 	pScrn->LeaveVT		= fbdevHWLeaveVTWeak();
1094 	pScrn->ValidMode	= fbdevHWValidModeWeak();
1095 
1096     } else {
1097     	/* Only use FBDev if requested */
1098 	pGlint->FBDev = FALSE;
1099         from = X_PROBED;
1100 
1101 	pScrn->AdjustFrame	= GLINTAdjustFrame;
1102 	pScrn->LeaveVT		= GLINTLeaveVT;
1103 	pScrn->ValidMode	= GLINTValidMode;
1104 
1105     }
1106     xf86DrvMsg(pScrn->scrnIndex, from, "%s Linux framebuffer device\n",
1107 		pGlint->FBDev ? "Using" : "Not using");
1108 
1109     pScrn->overlayFlags = 0;
1110     from = X_DEFAULT;
1111     if ((s = xf86GetOptValString(pGlint->Options, OPTION_OVERLAY))) {
1112 	if (!*s || !xf86NameCmp(s, "8,24") || !xf86NameCmp(s, "24,8")) {
1113 	    Overlay = TRUE;
1114 	} else {
1115 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1116 		"\"%s\" is not a valid value for Option \"Overlay\"\n", s);
1117 	}
1118     }
1119     if (Overlay) {
1120 	if ((pScrn->depth == 24) && (pScrn->bitsPerPixel == 32)) {
1121 	    pScrn->colorKey = 255; /* we should let the user change this */
1122 	    pScrn->overlayFlags = OVERLAY_8_32_PLANAR;
1123 	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "24/8 overlay enabled\n");
1124 	}
1125     }
1126 
1127     pGlint->DoubleBuffer = FALSE;
1128     pGlint->RamDac = NULL;
1129     pGlint->STATE = FALSE;
1130     /*
1131      * Set the Chipset and ChipRev, allowing config file entries to
1132      * override.
1133      */
1134     if (FBDevProbed) {	/* pm2fb so far only supports the Permedia2 */
1135     	pScrn->chipset = "ti_pm2";
1136         pGlint->Chipset = xf86StringToToken(GLINTChipsets, pScrn->chipset);
1137 	from = X_PROBED;
1138     } else {
1139     if (pGlint->pEnt->device->chipset && *pGlint->pEnt->device->chipset) {
1140 	pScrn->chipset = pGlint->pEnt->device->chipset;
1141         pGlint->Chipset = xf86StringToToken(GLINTChipsets, pScrn->chipset);
1142         from = X_CONFIG;
1143     } else if (pGlint->pEnt->device->chipID >= 0) {
1144 	pGlint->Chipset = pGlint->pEnt->device->chipID;
1145 	pScrn->chipset = (char *)xf86TokenToString(GLINTChipsets,
1146 						   pGlint->Chipset);
1147 
1148 	from = X_CONFIG;
1149 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
1150 		   pGlint->Chipset);
1151     } else {
1152 	from = X_PROBED;
1153 	pGlint->Chipset = PCI_DEV_VENDOR_ID(pGlint->PciInfo) << 16 |
1154  	                  PCI_DEV_DEVICE_ID(pGlint->PciInfo);
1155 	pScrn->chipset = (char *)xf86TokenToString(GLINTChipsets,
1156 						   pGlint->Chipset);
1157     }
1158     if (pGlint->pEnt->device->chipRev >= 0) {
1159 	pGlint->ChipRev = pGlint->pEnt->device->chipRev;
1160 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
1161 		   pGlint->ChipRev);
1162     } else {
1163         pGlint->ChipRev = PCI_DEV_REVISION(pGlint->PciInfo);
1164     }
1165     }
1166 
1167     /*
1168      * This shouldn't happen because such problems should be caught in
1169      * GLINTProbe(), but check it just in case.
1170      */
1171     if (pScrn->chipset == NULL) {
1172 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1173 		   "ChipID 0x%04X is not recognised\n", pGlint->Chipset);
1174 	return FALSE;
1175     }
1176     if (pGlint->Chipset < 0) {
1177 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1178 		   "Chipset \"%s\" is not recognised\n", pScrn->chipset);
1179 	return FALSE;
1180     }
1181 
1182     xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
1183 
1184     if ((pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2) ||
1185 	(pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) ||
1186 	(pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2)) {
1187     	if (xf86ReturnOptValBool(pGlint->Options, OPTION_BLOCK_WRITE, FALSE)) {
1188 	    pGlint->UseBlockWrite = TRUE;
1189 	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Block Writes enabled\n");
1190     	}
1191     }
1192 
1193     if (xf86ReturnOptValBool(pGlint->Options, OPTION_FIREGL3000, FALSE)) {
1194 	/* Can't we detect a Fire GL 3000 ????? and remove this ? */
1195 	pGlint->UseFireGL3000 = TRUE;
1196 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1197 			"Diamond FireGL3000 mode enabled\n");
1198     }
1199 
1200     if (!FBDevProbed) {
1201     if (pGlint->pEnt->device->MemBase != 0) {
1202 	/*
1203          * XXX Should check that the config file value matches one of the
1204 	 * PCI base address values.
1205 	 */
1206 	pGlint->FbAddress = pGlint->pEnt->device->MemBase;
1207 	from = X_CONFIG;
1208     } else {
1209         pGlint->FbAddress = PCI_REGION_BASE(pGlint->PciInfo, 2, REGION_MEM) & 0xFF800000;
1210     }
1211 
1212     if (pGlint->FbAddress)
1213     	xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
1214 	       (unsigned long)pGlint->FbAddress);
1215 
1216     /* Trap GAMMA & DELTA specification, with no linear address */
1217     /* Find the first GLINT chip and use that address */
1218     if (pGlint->FbAddress == 0) {
1219         if (PCI_REGION_BASE(pGlint->MultiPciInfo[0], 2, REGION_MEM)) {
1220 	    pGlint->FbAddress = PCI_REGION_BASE(pGlint->MultiPciInfo[0], 2, REGION_MEM);
1221 	    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1222 		"FrameBuffer used from first rasterizer chip at 0x%lx\n",
1223 				PCI_REGION_BASE(pGlint->MultiPciInfo[0], 2, REGION_MEM));
1224 	} else {
1225 	    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1226 			"No FrameBuffer memory - aborting\n");
1227 	    return FALSE;
1228 	}
1229     }
1230 
1231     if (pGlint->pEnt->device->IOBase != 0) {
1232 	/*
1233          * XXX Should check that the config file value matches one of the
1234 	 * PCI base address values.
1235 	 */
1236 	pGlint->IOAddress = pGlint->pEnt->device->IOBase;
1237 	from = X_CONFIG;
1238     } else {
1239 	pGlint->IOAddress = PCI_REGION_BASE(pGlint->PciInfo, 0, REGION_MEM) & 0xFFFFC000;
1240     }
1241 
1242     if ((IS_J2000) && (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) {
1243 	/* We know which head is the primary on the J2000 board, need a more
1244 	 * generix solution though.
1245 	 */
1246         if ((xf86IsEntityShared(pScrn->entityList[0])) &&
1247             (xf86IsPrimInitDone(pScrn->entityList[0]))) {
1248 		pGlint->IOAddress += 0x10000;
1249 		pGlint->MultiIndex = 2;
1250 	} else {
1251 		xf86SetPrimInitDone(pScrn->entityList[0]);
1252 		pGlint->MultiIndex = 1;
1253 	}
1254 #if X_BYTE_ORDER == X_BIG_ENDIAN
1255 	GLINT_SLOW_WRITE_REG(
1256 		GLINT_READ_REG(GCSRAperture) | GCSRBitSwap
1257 		, GCSRAperture);
1258     } else {
1259     	pGlint->IOAddress += 0x10000;
1260 #endif
1261     }
1262 
1263     xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
1264 	       (unsigned long)pGlint->IOAddress);
1265 
1266     pGlint->irq = pGlint->pEnt->device->irq;
1267 
1268 #ifndef XSERVER_LIBPCIACCESS
1269     /* Register all entities */
1270     for (i = 0; i < pScrn->numEntities; i++) {
1271 	EntityInfoPtr pEnt;
1272 	pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
1273         if (xf86RegisterResources(pEnt->index, NULL, ResExclusive)) {
1274 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1275 		   "xf86RegisterResources() found resource conflicts\n");
1276 	    return FALSE;
1277         }
1278     }
1279 #endif
1280     }
1281 
1282 
1283 #if !defined(__sparc__)
1284     /* Initialize the card through int10 interface if needed */
1285     if (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_GAMMA &&
1286 	pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_GAMMA2 &&
1287 	pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_DELTA &&
1288 	!xf86IsPrimaryPci(pGlint->PciInfo) && !pGlint->FBDev) {
1289     	if ( xf86LoadSubModule(pScrn, "int10")){
1290 	    xf86Int10InfoPtr pInt;
1291 
1292 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");
1293 	    pInt = xf86InitInt10(pGlint->pEnt->index);
1294 	    xf86FreeInt10(pInt);
1295         }
1296     }
1297 #endif
1298 
1299     pGlint->FbMapSize = 0;
1300 
1301     {
1302 	/* We have to boot some multiple head type boards here */
1303         GLINTMapMem(pScrn);
1304 	switch (pGlint->Chipset) {
1305             case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
1306             case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
1307 		Permedia3PreInit(pScrn);
1308 		break;
1309             case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
1310 		Permedia2VPreInit(pScrn);
1311 		break;
1312 	    case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
1313 	    case PCI_VENDOR_TI_CHIP_PERMEDIA2:
1314 		Permedia2PreInit(pScrn);
1315 		break;
1316 	    case PCI_VENDOR_3DLABS_CHIP_GAMMA:
1317 		switch (pGlint->MultiChip) {
1318 		case PCI_CHIP_3DLABS_PERMEDIA3:
1319 		    Permedia3PreInit(pScrn);
1320 		    break;
1321 		}
1322 		break;
1323 	    case PCI_VENDOR_3DLABS_CHIP_DELTA:
1324 		/* Delta has a bug, we need to fix it here */
1325 		{
1326 		    int basecopro =
1327 			PCI_REGION_BASE(pGlint->MultiPciInfo[0], 0, REGION_MEM) & 0xFFFFC000;
1328 		    int basedelta = PCI_REGION_BASE(pGlint->PciInfo, 0, REGION_MEM)  & 0xFFFFC000;
1329 		    uint32_t dummy;
1330 		    uint32_t base3copro, offset;
1331 
1332     		    if( (basedelta & 0x20000) ^ (basecopro & 0x20000) ) {
1333  			if ((pGlint->MultiChip == PCI_CHIP_3DLABS_PERMEDIA) ||
1334  			    (pGlint->MultiChip == PCI_CHIP_TI_PERMEDIA)) {
1335  			    offset = 0x20; /* base4 */
1336          		} else {
1337  			    offset = 0x1c; /* base3 */
1338  			}
1339 			PCI_READ_LONG(pGlint->MultiPciInfo[0], &base3copro, offset);
1340 			if( (basecopro & 0x20000) ^ (base3copro & 0x20000) ) {
1341 	    			/*
1342 	     		 	 * oops, still different; we know that base3
1343 	     		 	 * is at least 16 MB, so we just take 128k
1344 				 * offset into it.
1345 	     		 	 */
1346 	    			base3copro += 0x20000;
1347 			}
1348 			/*
1349 	 		 * and now for the magic.
1350 	 		 * read old value
1351 	 		 * write fffffffff
1352 	 		 * read value
1353 	 		 * write new value
1354 	 		 */
1355 			PCI_READ_LONG(pGlint->PciInfo, &dummy, 0x10);
1356 			PCI_WRITE_LONG(pGlint->PciInfo, 0xffffffff, 0x10);
1357 			PCI_READ_LONG(pGlint->PciInfo, &dummy, 0x10);
1358 			PCI_WRITE_LONG(pGlint->PciInfo, base3copro, 0x10);
1359 
1360 			/*
1361 	 		 * additionally,sometimes we see the baserom which might
1362 	 		 * confuse the chip, so let's make sure that is disabled
1363 	 		 */
1364 			PCI_READ_LONG(pGlint->MultiPciInfo[0], &dummy, 0x30);
1365 			PCI_WRITE_LONG(pGlint->MultiPciInfo[0], 0xffffffff, 0x30);
1366 			PCI_READ_LONG(pGlint->MultiPciInfo[0], &dummy, 0x30);
1367 			PCI_WRITE_LONG(pGlint->MultiPciInfo[0], 0, 0x30);
1368 
1369 			/*
1370 	 		 * now update our internal structure accordingly
1371 	 		 */
1372 			pGlint->IOAddress = base3copro;
1373 #ifndef XSERVER_LIBPCIACCESS
1374 			pGlint->PciInfo->memBase[0] = base3copro;
1375 #endif
1376     			xf86DrvMsg(pScrn->scrnIndex, from,
1377 			       "Delta Bug - Changing MMIO registers to 0x%lX\n",
1378 	       		       (unsigned long)pGlint->IOAddress);
1379     		    }
1380 		}
1381 		break;
1382 	    default:
1383 		break;
1384 	}
1385        	GLINTUnmapMem(pScrn);
1386     }
1387 
1388     /* HW bpp matches reported bpp */
1389     pGlint->HwBpp = pScrn->bitsPerPixel;
1390 
1391     pGlint->FbBase = NULL;
1392     if (!FBDevProbed) {
1393     	if (pGlint->pEnt->device->videoRam != 0) {
1394 		pScrn->videoRam = pGlint->pEnt->device->videoRam;
1395 		from = X_CONFIG;
1396     	} else {
1397 		/* Need to access MMIO to determine videoRam */
1398         	GLINTMapMem(pScrn);
1399 		switch (pGlint->Chipset) {
1400 		case PCI_VENDOR_3DLABS_CHIP_500TX:
1401 		case PCI_VENDOR_3DLABS_CHIP_300SX:
1402 		case PCI_VENDOR_3DLABS_CHIP_MX:
1403 	    	    pScrn->videoRam = (1 << ((GLINT_READ_REG(FBMemoryCtl) &
1404 						0xE0000000)>>29)) * 1024;
1405 		    break;
1406     		case PCI_VENDOR_TI_CHIP_PERMEDIA2:
1407     		case PCI_VENDOR_TI_CHIP_PERMEDIA:
1408 		case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
1409 		case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
1410 		case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
1411 	    	    pScrn->videoRam = (((GLINT_READ_REG(PMMemConfig) >> 29) &
1412 							0x03) + 1) * 2048;
1413 		    break;
1414 		case PCI_VENDOR_3DLABS_CHIP_R4:
1415 		case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
1416 		case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
1417 		    pScrn->videoRam = Permedia3MemorySizeDetect(pScrn);
1418 		    break;
1419 		case PCI_VENDOR_3DLABS_CHIP_DELTA:
1420 		case PCI_VENDOR_3DLABS_CHIP_GAMMA:
1421 		case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
1422 		    switch (pGlint->MultiChip) {
1423 		    case PCI_CHIP_3DLABS_PERMEDIA:
1424 		    case PCI_CHIP_TI_PERMEDIA:
1425 	    	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1426 				     "Attached Rasterizer is GLINT Permedia\n");
1427 	    	        pScrn->videoRam = (((GLINT_READ_REG(PMMemConfig)>>29) &
1428 							0x03) + 1) * 2048;
1429 		 	break;
1430 		    case PCI_CHIP_3DLABS_300SX:
1431 	    	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1432 				     "Attached Rasterizer is GLINT 300SX\n");
1433 	    	    	pScrn->videoRam = (1 << ((GLINT_READ_REG(FBMemoryCtl) &
1434 						0xE0000000)>>29)) * 1024;
1435 		    	break;
1436 		    case PCI_CHIP_3DLABS_500TX:
1437 	    	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1438 				     "Attached Rasterizer is GLINT 500TX\n");
1439 	    	    	pScrn->videoRam = (1 << ((GLINT_READ_REG(FBMemoryCtl) &
1440 						0xE0000000)>>29)) * 1024;
1441 		    	break;
1442 		    case PCI_CHIP_3DLABS_MX:
1443 	    	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1444 				       "Attached Rasterizer is GLINT MX\n");
1445 	    	        pScrn->videoRam =
1446 					(1 << ((GLINT_READ_REG(FBMemoryCtl) &
1447 						0xE0000000)>>29)) * 1024;
1448 			break;
1449 		    case PCI_CHIP_3DLABS_PERMEDIA3:
1450 	    	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1451 					"Attached Rasterizer is Permedia3\n");
1452 		        pScrn->videoRam = Permedia3MemorySizeDetect(pScrn);
1453 			break;
1454 		    case PCI_CHIP_3DLABS_R4:
1455 	    	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1456 					"Attached Rasterizer is R4\n");
1457 		        pScrn->videoRam = Permedia3MemorySizeDetect(pScrn);
1458 			break;
1459 		    }
1460 	    	    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1461 				"Number of Rasterizers attached is %d\n",
1462 					pGlint->numMultiDevices);
1463 		    break;
1464 		}
1465         	GLINTUnmapMem(pScrn);
1466     	}
1467     } else {
1468     	pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024;
1469     }
1470 
1471     pGlint->FbMapSize = pScrn->videoRam * 1024;
1472 
1473     /* OVERRIDE videoRam/FbMapSize, for Multiply connected chips to GAMMA */
1474     pGlint->MultiAperture = FALSE;
1475     if ( ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) ||
1476           (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA2)) &&
1477          (pGlint->numMultiDevices == 2) ) {
1478 	CARD32 chipconfig;
1479 	CARD32 size = 0;
1480 
1481 	GLINTMapMem(pScrn);
1482 
1483 	(void) GLINT_READ_REG(GCSRAperture);
1484 	GLINT_SLOW_WRITE_REG(GCSRSecondaryGLINTMapEn, GCSRAperture);
1485 
1486 	chipconfig = GLINT_READ_REG(GChipConfig);
1487 
1488 	GLINT_SLOW_WRITE_REG(GCSRSecondaryGLINTMapEn, GCSRAperture);
1489 
1490 	GLINTUnmapMem(pScrn);
1491 
1492 	switch (chipconfig & GChipMultiGLINTApMask) {
1493 	case GChipMultiGLINTAp_0M:
1494 	    size = 0;
1495 	    break;
1496 	case GChipMultiGLINTAp_16M:
1497 	    size = 16 * 1024 * 1024;
1498 	    break;
1499 	case GChipMultiGLINTAp_32M:
1500 	    size = 32 * 1024 * 1024;
1501 	    break;
1502 	case GChipMultiGLINTAp_64M:
1503 	    size = 64 * 1024 * 1024;
1504 	    break;
1505 	}
1506 
1507 	if (size == 0) {
1508     	    xf86DrvMsg(pScrn->scrnIndex, from, "MultiAperture: disabled\n");
1509 	} else {
1510     	    xf86DrvMsg(pScrn->scrnIndex, from, "MultiAperture: enabled\n");
1511 	    pGlint->FbMapSize = size;
1512 	    pGlint->MultiAperture = TRUE;
1513 	}
1514     }
1515 
1516     xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %ld kByte\n",
1517 		   pGlint->FbMapSize / 1024);
1518 
1519     /* The ramdac module should be loaded here when needed */
1520     if (!xf86LoadSubModule(pScrn, "ramdac"))
1521 	return FALSE;
1522 
1523     /* Let's check what type of DAC we have and reject if necessary */
1524     switch (pGlint->Chipset) {
1525 	case PCI_VENDOR_TI_CHIP_PERMEDIA2:
1526 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
1527 	    pGlint->FIFOSize = 256;
1528 	    maxheight = 2048;
1529 	    maxwidth = 2048;
1530 	    pGlint->RefClock = 14318;
1531 	    pGlint->RamDacRec = RamDacCreateInfoRec();
1532 	    pGlint->RamDacRec->ReadDAC = Permedia2InIndReg;
1533 	    pGlint->RamDacRec->WriteDAC = Permedia2OutIndReg;
1534 	    pGlint->RamDacRec->ReadAddress = Permedia2ReadAddress;
1535 	    pGlint->RamDacRec->WriteAddress = Permedia2WriteAddress;
1536 	    pGlint->RamDacRec->ReadData = Permedia2ReadData;
1537 	    pGlint->RamDacRec->WriteData = Permedia2WriteData;
1538 	    if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
1539 		RamDacDestroyInfoRec(pGlint->RamDacRec);
1540 		return FALSE;
1541 	    }
1542 	    break;
1543 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
1544 	    pGlint->FIFOSize = 256;
1545 	    maxheight = 2048;
1546 	    maxwidth = 2048;
1547 	    pGlint->RefClock = 14318;
1548 	    pGlint->RamDacRec = RamDacCreateInfoRec();
1549 	    pGlint->RamDacRec->ReadDAC = Permedia2vInIndReg;
1550 	    pGlint->RamDacRec->WriteDAC = Permedia2vOutIndReg;
1551 	    pGlint->RamDacRec->ReadAddress = Permedia2ReadAddress;
1552 	    pGlint->RamDacRec->WriteAddress = Permedia2WriteAddress;
1553 	    pGlint->RamDacRec->ReadData = Permedia2ReadData;
1554 	    pGlint->RamDacRec->WriteData = Permedia2WriteData;
1555 	    if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
1556 		RamDacDestroyInfoRec(pGlint->RamDacRec);
1557 		return FALSE;
1558 	    }
1559 	    break;
1560 	case PCI_VENDOR_3DLABS_CHIP_R4:
1561 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
1562 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
1563 	    if (pScrn->bitsPerPixel == 24) {
1564 		xf86DrvMsg(pScrn->scrnIndex, from,
1565 			"-depth 24 -pixmap24 not supported by this chip.\n");
1566 		return FALSE;
1567 	    }
1568 	    pGlint->FIFOSize = 120;
1569 	    maxheight = 4096;
1570 	    maxwidth = 4096;
1571 	    pGlint->RefClock = 14318;
1572 	    pGlint->RamDacRec = RamDacCreateInfoRec();
1573 	    pGlint->RamDacRec->ReadDAC = Permedia2vInIndReg;
1574 	    pGlint->RamDacRec->WriteDAC = Permedia2vOutIndReg;
1575 	    pGlint->RamDacRec->ReadAddress = Permedia2ReadAddress;
1576 	    pGlint->RamDacRec->WriteAddress = Permedia2WriteAddress;
1577 	    pGlint->RamDacRec->ReadData = Permedia2ReadData;
1578 	    pGlint->RamDacRec->WriteData = Permedia2WriteData;
1579 	    if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
1580 		RamDacDestroyInfoRec(pGlint->RamDacRec);
1581 		return FALSE;
1582 	    }
1583 	    break;
1584 	case PCI_VENDOR_TI_CHIP_PERMEDIA:
1585 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
1586 	    pGlint->FIFOSize = 31;
1587 	    maxheight = 1024;
1588 	    maxwidth = 1536;
1589 	    /* Test for an TI ramdac */
1590 	    if (!pGlint->RamDac) {
1591 	    	GLINTProbeTIramdac(pScrn);
1592 		if (pGlint->RamDac)
1593 	             if (pGlint->RamDac->RamDacType == (TI3026_RAMDAC))
1594 		    	pGlint->RefClock = 14318;
1595 	    }
1596 	    /* Test for an IBM ramdac */
1597 	    if (!pGlint->RamDac) {
1598 	    	GLINTProbeIBMramdac(pScrn);
1599 		if (pGlint->RamDac) {
1600 	    	    if (pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC) ||
1601 		    	pGlint->RamDac->RamDacType == (IBM526_RAMDAC))
1602 		    	pGlint->RefClock = 14318;
1603 		}
1604 	    }
1605 	    if (!pGlint->RamDac)
1606 		return FALSE;
1607 	    break;
1608 	case PCI_VENDOR_3DLABS_CHIP_500TX:
1609 	case PCI_VENDOR_3DLABS_CHIP_300SX:
1610 	case PCI_VENDOR_3DLABS_CHIP_MX:
1611 	    pGlint->FIFOSize = 15;
1612 	    if (pScrn->bitsPerPixel == 24) {
1613 		xf86DrvMsg(pScrn->scrnIndex, from,
1614 			"-depth 24 -pixmap24 not supported by this chip.\n");
1615 		return FALSE;
1616 	    }
1617 	    maxheight = 4096;
1618 	    maxwidth = 4096;
1619 	    /* Test for an TI ramdac */
1620 	    if (!pGlint->RamDac) {
1621 	    	GLINTProbeTIramdac(pScrn);
1622 		if (pGlint->RamDac)
1623 	             if ( (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) ||
1624 	         	  (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) )
1625 		    	pGlint->RefClock = 14318;
1626 	    }
1627 	    /* Test for an IBM ramdac */
1628 	    if (!pGlint->RamDac) {
1629 	    	GLINTProbeIBMramdac(pScrn);
1630 		if (pGlint->RamDac) {
1631 	    	    if (pGlint->RamDac->RamDacType == (IBM640_RAMDAC))
1632 		    	pGlint->RefClock = 28322;
1633 	    	    else
1634 	    	    if (pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC) ||
1635 		    	pGlint->RamDac->RamDacType == (IBM526_RAMDAC))
1636 		    	pGlint->RefClock = 40000;
1637 		}
1638 	    }
1639 	    if (!pGlint->RamDac)
1640 		return FALSE;
1641 	    break;
1642 	case PCI_VENDOR_3DLABS_CHIP_DELTA:
1643 	    pGlint->FIFOSize = 15;
1644 	    switch (pGlint->MultiChip) {
1645 		case PCI_CHIP_3DLABS_PERMEDIA:
1646 		case PCI_CHIP_TI_PERMEDIA:
1647 	    	    maxheight = 1024;
1648 	    	    maxwidth = 1536;
1649 	    	    /* Test for an TI ramdac */
1650 	    	    if (!pGlint->RamDac) {
1651 	    		GLINTProbeTIramdac(pScrn);
1652 			if (pGlint->RamDac)
1653 	             	    if (pGlint->RamDac->RamDacType == (TI3026_RAMDAC))
1654 		    		pGlint->RefClock = 14318;
1655 	    	    }
1656 	    	    /* Test for an IBM ramdac */
1657 	    	    if (!pGlint->RamDac) {
1658 	    		GLINTProbeIBMramdac(pScrn);
1659 			if (pGlint->RamDac) {
1660 	    	    	    if (pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC) ||
1661 		    		pGlint->RamDac->RamDacType == (IBM526_RAMDAC))
1662 		    		    pGlint->RefClock = 14318;
1663 			}
1664 	    	    }
1665 	    	    if (!pGlint->RamDac)
1666 			return FALSE;
1667 		    break;
1668 		case PCI_CHIP_3DLABS_500TX:
1669 		case PCI_CHIP_3DLABS_300SX:
1670 		case PCI_CHIP_3DLABS_MX:
1671 	    	    if (pScrn->bitsPerPixel == 24) {
1672 			xf86DrvMsg(pScrn->scrnIndex, from,
1673 			  "-depth 24 -pixmap24 not supported by this chip.\n");
1674 			return FALSE;
1675 	    	    }
1676 	    	    maxheight = 4096;
1677 	    	    maxwidth = 4096;
1678 	    	    /* Test for an TI ramdac */
1679 	    	    if (!pGlint->RamDac) {
1680 	    	   	GLINTProbeTIramdac(pScrn);
1681 			if (pGlint->RamDac)
1682 	                if ( (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) ||
1683 	         	      (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) )
1684 		    		pGlint->RefClock = 14318;
1685 	    	    }
1686 	    	    /* Test for an IBM ramdac */
1687 	    	    if (!pGlint->RamDac) {
1688 	    		GLINTProbeIBMramdac(pScrn);
1689 			if (pGlint->RamDac) {
1690 	    	    	 if (pGlint->RamDac->RamDacType == (IBM640_RAMDAC) ||
1691 	    	    	     pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC) ||
1692 		    	     pGlint->RamDac->RamDacType == (IBM526_RAMDAC))
1693 		    		pGlint->RefClock = 40000;
1694 		    	}
1695 	    	    }
1696 	    	    break;
1697 	    }
1698 	    break;
1699 	case PCI_VENDOR_3DLABS_CHIP_GAMMA:
1700 	case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
1701 	    pGlint->FIFOSize = 32;
1702 	    if (pScrn->bitsPerPixel == 24) {
1703 		xf86DrvMsg(pScrn->scrnIndex, from,
1704 			"-depth 24 -pixmap24 not supported by this chip.\n");
1705 		return FALSE;
1706 	    }
1707 	    maxheight = 4096;
1708 	    maxwidth = 4096;
1709 	    /* Let's do board specific stuff first */
1710 	    if (IS_J2000) {
1711 		xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1712 			"Appian Jeronimo 2000 board detected\n");
1713 	    	pGlint->RefClock = 14318;
1714 	    	pGlint->RamDacRec = RamDacCreateInfoRec();
1715 	    	pGlint->RamDacRec->ReadDAC = Permedia2vInIndReg;
1716 	    	pGlint->RamDacRec->WriteDAC = Permedia2vOutIndReg;
1717 	    	pGlint->RamDacRec->ReadAddress = Permedia2ReadAddress;
1718 	    	pGlint->RamDacRec->WriteAddress = Permedia2WriteAddress;
1719 	    	pGlint->RamDacRec->ReadData = Permedia2ReadData;
1720 	    	pGlint->RamDacRec->WriteData = Permedia2WriteData;
1721 	    	if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
1722 		    RamDacDestroyInfoRec(pGlint->RamDacRec);
1723 		    return FALSE;
1724 	    	}
1725 		break;
1726 	    }
1727 	    if (IS_GMX2000) {
1728 		xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1729 			"3DLabs GMX2000 board detected\n");
1730 		/* We need to wrap these after detection as the second MX
1731 		 * is the only chip that can write to the TI3030 dac */
1732 		ACCESSCHIP2();
1733 	    	GLINTProbeTIramdac(pScrn);
1734 		ACCESSCHIP1();
1735     		pGlint->RamDacRec->ReadDAC = GMX2000InIndReg;
1736     		pGlint->RamDacRec->WriteDAC = GMX2000OutIndReg;
1737     		pGlint->RamDacRec->ReadAddress = GMX2000ReadAddress;
1738     		pGlint->RamDacRec->WriteAddress = GMX2000WriteAddress;
1739     		pGlint->RamDacRec->ReadData = GMX2000ReadData;
1740     		pGlint->RamDacRec->WriteData = GMX2000WriteData;
1741 		pGlint->RefClock = 14318;
1742 		break;
1743 	    }
1744 	    /* Test for an TI ramdac */
1745 	    if (!pGlint->RamDac) {
1746 	    	GLINTProbeTIramdac(pScrn);
1747 		if (pGlint->RamDac)
1748 	             if ( (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) ||
1749 	         	  (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) )
1750 		    	pGlint->RefClock = 14318;
1751 	    }
1752 	    /* Test for an IBM ramdac */
1753 	    if (!pGlint->RamDac) {
1754 	    	GLINTProbeIBMramdac(pScrn);
1755 		if (pGlint->RamDac) {
1756 	    	    if (pGlint->RamDac->RamDacType == (IBM640_RAMDAC))
1757 		    	pGlint->RefClock = 28322;
1758 	    	    else
1759 	    	    if (pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC) ||
1760 		    	pGlint->RamDac->RamDacType == (IBM526_RAMDAC))
1761 		    	pGlint->RefClock = 40000;
1762 		}
1763 	    }
1764  	    if (!pGlint->RamDac) {
1765 		if ((pGlint->MultiChip == PCI_CHIP_3DLABS_PERMEDIA3) ||
1766 		    (pGlint->MultiChip == PCI_CHIP_3DLABS_R4)) {
1767 	    	    pGlint->RefClock = 14318;
1768 	    	    pGlint->RamDacRec = RamDacCreateInfoRec();
1769 	    	    pGlint->RamDacRec->ReadDAC = Permedia2vInIndReg;
1770 	    	    pGlint->RamDacRec->WriteDAC = Permedia2vOutIndReg;
1771 	    	    pGlint->RamDacRec->ReadAddress = Permedia2ReadAddress;
1772 	    	    pGlint->RamDacRec->WriteAddress = Permedia2WriteAddress;
1773 	    	    pGlint->RamDacRec->ReadData = Permedia2ReadData;
1774 	    	    pGlint->RamDacRec->WriteData = Permedia2WriteData;
1775 		}
1776 	    	if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
1777 		    RamDacDestroyInfoRec(pGlint->RamDacRec);
1778 		    return FALSE;
1779 	        }
1780 	    } else
1781 	    	if (!pGlint->RamDac)
1782 		    return FALSE;
1783 	    break;
1784     }
1785 
1786     if ( pGlint->RamDac &&
1787 	 (pGlint->RamDac->RamDacType != (IBM640_RAMDAC)) &&
1788 	 (pScrn->depth == 30) )
1789     {
1790     	xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1791 			"Depth 30 not supported for this chip\n");
1792 	return FALSE;
1793     }
1794 
1795     if (pGlint->FIFOSize)
1796     	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "FIFO Size is %d DWORDS\n",
1797 	       pGlint->FIFOSize);
1798 
1799     /* Set the min pixel clock */
1800     pGlint->MinClock = 16250;	/* XXX Guess, need to check this */
1801     xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
1802 	       pGlint->MinClock / 1000);
1803 
1804     /*
1805      * If the user has specified ramdac speed in the XF86Config
1806      * file, we respect that setting.
1807      */
1808     if (pGlint->pEnt->device->dacSpeeds[0]) {
1809 	int speed = 0;
1810 
1811 	switch (pScrn->bitsPerPixel) {
1812 	case 8:
1813 	   speed = pGlint->pEnt->device->dacSpeeds[DAC_BPP8];
1814 	   break;
1815 	case 16:
1816 	   speed = pGlint->pEnt->device->dacSpeeds[DAC_BPP16];
1817 	   break;
1818 	case 24:
1819 	   speed = pGlint->pEnt->device->dacSpeeds[DAC_BPP24];
1820 	   break;
1821 	case 32:
1822 	   speed = pGlint->pEnt->device->dacSpeeds[DAC_BPP32];
1823 	   break;
1824 	}
1825 	if (speed == 0)
1826 	    pGlint->MaxClock = pGlint->pEnt->device->dacSpeeds[0];
1827 	else
1828 	    pGlint->MaxClock = speed;
1829 	from = X_CONFIG;
1830     } else {
1831 	if((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX)||
1832 	   (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_300SX) ||
1833 	   (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) ||
1834 	   ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
1835 	    (pGlint->MultiChip == PCI_CHIP_3DLABS_300SX)) ||
1836 	   ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
1837 	    (pGlint->MultiChip == PCI_CHIP_3DLABS_500TX)) ||
1838 	   ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
1839 	    (pGlint->MultiChip == PCI_CHIP_3DLABS_MX)) ||
1840 	   ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
1841 	    (pGlint->MultiChip == PCI_CHIP_3DLABS_MX)) )
1842 		pGlint->MaxClock = 220000;
1843 	if ( (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA) ||
1844 	     (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA) ||
1845 	     ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
1846 	      ((pGlint->MultiChip == PCI_CHIP_3DLABS_PERMEDIA) ||
1847 	       (pGlint->MultiChip == PCI_CHIP_TI_PERMEDIA))) ) {
1848 		switch (pScrn->bitsPerPixel) {
1849 		    case 8:
1850 			pGlint->MaxClock = 200000;
1851 			break;
1852 		    case 16:
1853 			pGlint->MaxClock = 100000;
1854 			break;
1855 		    case 24:
1856 			pGlint->MaxClock = 50000;
1857 			break;
1858 		    case 32:
1859 			pGlint->MaxClock = 50000;
1860 			break;
1861 		}
1862 	}
1863 	if ( (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2) ||
1864 	     (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) ||
1865 	     (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) ) {
1866 		switch (pScrn->bitsPerPixel) {
1867 		    case 8:
1868 			pGlint->MaxClock = 230000;
1869 			break;
1870 		    case 16:
1871 			pGlint->MaxClock = 230000;
1872 			break;
1873 		    case 24:
1874 			pGlint->MaxClock = 150000;
1875 			break;
1876 		    case 32:
1877 			pGlint->MaxClock = 110000;
1878 			break;
1879 		}
1880 	}
1881 	if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) ||
1882 	    (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) ||
1883 	    (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_R4) ||
1884 	    ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA2) &&
1885 	     (pGlint->MultiChip == PCI_CHIP_3DLABS_R4)) ||
1886 	    ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
1887 	     (pGlint->MultiChip == PCI_CHIP_3DLABS_PERMEDIA3)) )
1888 	    pGlint->MaxClock = 300000;
1889     }
1890     xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
1891 	       pGlint->MaxClock / 1000);
1892 
1893     /* Load DDC */
1894     if (!xf86LoadSubModule(pScrn, "ddc")) {
1895 	GLINTFreeRec(pScrn);
1896 	return FALSE;
1897     }
1898     /* Load I2C if needed */
1899     if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) ||
1900 	(pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) ||
1901 	(pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) ||
1902 	(pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) ||
1903 	(pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_R4) ||
1904 	(pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2)) {
1905 	if (xf86LoadSubModule(pScrn, "i2c")) {
1906 	    I2CBusPtr pBus;
1907 
1908 	    if ((pBus = xf86CreateI2CBusRec())) {
1909 		pBus->BusName = "DDC";
1910 		pBus->scrnIndex = pScrn->scrnIndex;
1911 		pBus->I2CUDelay = Permedia2I2CUDelay;
1912 		pBus->I2CPutBits = Permedia2I2CPutBits;
1913 		pBus->I2CGetBits = Permedia2I2CGetBits;
1914 		pBus->DriverPrivate.ptr = pGlint;
1915 		if (!xf86I2CBusInit(pBus)) {
1916 		    xf86DestroyI2CBusRec(pBus, TRUE, TRUE);
1917 		} else
1918 		    pGlint->DDCBus = pBus;
1919 	    }
1920 
1921 	    if ((pBus = xf86CreateI2CBusRec())) {
1922 	        pBus->BusName = "Video";
1923 	        pBus->scrnIndex = pScrn->scrnIndex;
1924 		pBus->I2CUDelay = Permedia2I2CUDelay;
1925 		pBus->I2CPutBits = Permedia2I2CPutBits;
1926 		pBus->I2CGetBits = Permedia2I2CGetBits;
1927 		pBus->DriverPrivate.ptr = pGlint;
1928 		if (!xf86I2CBusInit(pBus)) {
1929 		    xf86DestroyI2CBusRec(pBus, TRUE, TRUE);
1930 		} else
1931 		    pGlint->VSBus = pBus;
1932 	    }
1933 	}
1934     }
1935 
1936     /* DDC */
1937     {
1938 	xf86MonPtr pMon = NULL;
1939 
1940 	if (pGlint->DDCBus) {
1941 	    GLINTMapMem(pScrn);
1942 	    pMon = xf86DoEDID_DDC2(XF86_SCRN_ARG(pScrn), pGlint->DDCBus);
1943 	    GLINTUnmapMem(pScrn);
1944 	}
1945 
1946 	if (!pMon)
1947 	    /* Try DDC1 */;
1948 
1949 	xf86SetDDCproperties(pScrn,xf86PrintEDID(pMon));
1950     }
1951 
1952     /*
1953      * Setup the ClockRanges, which describe what clock ranges are available,
1954      * and what sort of modes they can be used for.
1955      */
1956     clockRanges = xnfcalloc(sizeof(ClockRange), 1);
1957     clockRanges->next = NULL;
1958     clockRanges->minClock = pGlint->MinClock;
1959     clockRanges->maxClock = pGlint->MaxClock;
1960     clockRanges->clockIndex = -1;		/* programmable */
1961     clockRanges->interlaceAllowed = FALSE;	/* XXX check this */
1962     clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
1963 
1964     /*
1965      * xf86ValidateModes will check that the mode HTotal and VTotal values
1966      * don't exceed the chipset's limit if pScrn->maxHValue and
1967      * pScrn->maxVValue are set.  Since our GLINTValidMode() already takes
1968      * care of this, we don't worry about setting them here.
1969      */
1970 
1971     /* Select valid modes from those available */
1972     if ((pGlint->NoAccel) ||
1973 	(pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) ||
1974 	(pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) ||
1975 	(pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_R4) ||
1976 	((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA2) &&
1977 	 (pGlint->MultiChip == PCI_CHIP_3DLABS_R4)) ||
1978 	((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
1979 	 (pGlint->MultiChip == PCI_CHIP_3DLABS_PERMEDIA3)) ) {
1980 	/*
1981 	 * XXX Assuming min pitch 256, max <maxwidth>
1982 	 * XXX Assuming min height 128, max <maxheight>
1983 	 */
1984 	i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
1985 			      pScrn->display->modes, clockRanges,
1986 			      NULL, 256, maxwidth,
1987 			      pScrn->bitsPerPixel, 128, maxheight,
1988 			      pScrn->display->virtualX,
1989 			      pScrn->display->virtualY,
1990 			      pGlint->FbMapSize,
1991 			      LOOKUP_BEST_REFRESH);
1992     } else {
1993 	/*
1994 	 * Minimum width 32, Maximum width <maxwidth>
1995 	 * Minimum height 128, Maximum height <maxheight>
1996 	 */
1997 	i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
1998 			      pScrn->display->modes, clockRanges,
1999 			      GetAccelPitchValues(pScrn), 32, maxwidth,
2000 			      pScrn->bitsPerPixel, 128, maxheight,
2001 			      pScrn->display->virtualX,
2002 			      pScrn->display->virtualY,
2003 			      pGlint->FbMapSize,
2004 			      LOOKUP_BEST_REFRESH);
2005     }
2006 
2007     if (i < 1 && pGlint->FBDev) {
2008 	fbdevHWUseBuildinMode(pScrn);
2009 	i = 1;
2010     }
2011 
2012     if (i == -1) {
2013 	GLINTFreeRec(pScrn);
2014 	return FALSE;
2015     }
2016 
2017     if (i == 0 || pScrn->modes == NULL) {
2018 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
2019 	GLINTFreeRec(pScrn);
2020 	return FALSE;
2021     }
2022 
2023     if (pGlint->FBDev) {
2024 	/* shift horizontal timings for 64bit VRAM's or 32bit SGRAMs */
2025 	switch (pScrn->bitsPerPixel) {
2026 	case 8:
2027 		pGlint->BppShift = 2;
2028 		break;
2029 	case 16:
2030 		if (pGlint->DoubleBuffer) {
2031 	    		pGlint->BppShift = 0;
2032 		} else {
2033 	    		pGlint->BppShift = 1;
2034 		}
2035 		break;
2036 	case 24:
2037 		pGlint->BppShift = 2;
2038 		break;
2039 	case 32:
2040 		pGlint->BppShift = 0;
2041 		break;
2042 	}
2043 
2044 	pScrn->displayWidth = pScrn->virtualX;
2045 
2046 	/* Ensure vsync and hsync are high when using HW cursor */
2047 	if (pGlint->HWCursor) {
2048 		DisplayModePtr mode, first = mode = pScrn->modes;
2049 
2050 		do {	/* We know there is at least the built-in mode */
2051 			mode->Flags |= V_PHSYNC | V_PVSYNC;
2052 			mode->Flags &= ~V_NHSYNC | ~V_NVSYNC;
2053 			mode = mode->next;
2054 		} while (mode != NULL && mode != first);
2055 	}
2056     }
2057 
2058     /* Prune the modes marked as invalid */
2059     xf86PruneDriverModes(pScrn);
2060 
2061     /* Only allow a single mode for MX and TX chipsets */
2062     if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX) ||
2063         (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_300SX) ||
2064         (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) ||
2065         ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
2066 	 (pGlint->MultiChip == PCI_CHIP_3DLABS_300SX)) ||
2067         ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
2068 	 (pGlint->MultiChip == PCI_CHIP_3DLABS_500TX)) ||
2069         ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
2070 	 (pGlint->MultiChip == PCI_CHIP_3DLABS_MX)) ||
2071         ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
2072 	 (pGlint->MultiChip == PCI_CHIP_3DLABS_MX)) ) {
2073 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2074 	    "This GLINT chip only supports one modeline, using first\n");
2075 	pScrn->modes->next = NULL;
2076 	pScrn->virtualX = pScrn->modes->HDisplay;
2077 	pScrn->virtualY = pScrn->modes->VDisplay;
2078 	pScrn->displayWidth = pScrn->virtualX;
2079 	if (partprod500TX[pScrn->displayWidth >> 5] == -1) {
2080 	    i = -1;
2081 	    do {
2082 	        pScrn->displayWidth += 32;
2083 	        i = partprod500TX[pScrn->displayWidth >> 5];
2084 	    } while (i == -1);
2085 	}
2086     }
2087 
2088     /* Check Virtual resolution */
2089     if (pScrn->virtualX > maxwidth) {
2090 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2091 		    "GLINTModeInit: virtual width (%d) too big for hardware\n",
2092 		    pScrn->virtualX);
2093 	return FALSE;
2094     }
2095     if (pScrn->virtualY > maxheight) {
2096 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2097 		    "GLINTModeInit: virtual height (%d) too big for hardware\n",
2098 		    pScrn->virtualY);
2099 	return FALSE;
2100     }
2101 
2102     switch (pGlint->Chipset)
2103     { /* Now we know displaywidth, so set linepitch data */
2104     case PCI_VENDOR_TI_CHIP_PERMEDIA2:
2105     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
2106     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
2107     case PCI_VENDOR_TI_CHIP_PERMEDIA:
2108     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
2109 	pGlint->pprod = partprodPermedia[pScrn->displayWidth >> 5];
2110 	pGlint->bppalign = bppand[(pScrn->bitsPerPixel>>3)-1];
2111 	break;
2112     case PCI_VENDOR_3DLABS_CHIP_500TX:
2113     case PCI_VENDOR_3DLABS_CHIP_MX:
2114     case PCI_VENDOR_3DLABS_CHIP_300SX:
2115 	pGlint->pprod = partprod500TX[pScrn->displayWidth >> 5];
2116 	pGlint->bppalign = 0;
2117 	break;
2118     case PCI_VENDOR_3DLABS_CHIP_GAMMA:
2119     case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
2120     case PCI_VENDOR_3DLABS_CHIP_DELTA:
2121 	switch (pGlint->MultiChip) {
2122 	case PCI_CHIP_3DLABS_MX:
2123 	case PCI_CHIP_3DLABS_500TX:
2124 	case PCI_CHIP_3DLABS_300SX:
2125 	    pGlint->pprod = partprod500TX[pScrn->displayWidth >> 5];
2126 	    pGlint->bppalign = 0;
2127 	    break;
2128     	case PCI_CHIP_3DLABS_PERMEDIA:
2129     	case PCI_CHIP_TI_PERMEDIA:
2130 	    pGlint->pprod = partprodPermedia[pScrn->displayWidth >> 5];
2131 	    pGlint->bppalign = bppand[(pScrn->bitsPerPixel>>3)-1];
2132 	    break;
2133 	}
2134 	break;
2135     }
2136 
2137     if ( ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) ||
2138           (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA2)) &&
2139          (pGlint->numMultiDevices == 2) ) {
2140 	int bytesPerPixel, realWidthBytes, inputXSpanBytes;
2141 	CARD32 postMultiply, productEnable, use16xProduct, inputXSpan;
2142 	CARD32 binaryEval, glintApSize;
2143 
2144 	/* setup multi glint framebuffer aperture */
2145 	bytesPerPixel = (pScrn->bitsPerPixel >> 3);
2146 	realWidthBytes = pScrn->displayWidth * bytesPerPixel;
2147 
2148 	/* compute Input X Span field */
2149 	binaryEval = ((realWidthBytes << 1) - 1);
2150 	if (binaryEval & (8 << 10)) {      /* 8K */
2151 	    inputXSpan = 3;
2152 	    inputXSpanBytes = 8 * 1024;
2153 	}
2154 	else if (binaryEval & (4 << 10)) { /* 4K */
2155 	    inputXSpan = 2;
2156 	    inputXSpanBytes = 4 * 1024;
2157 	}
2158 	else if (binaryEval & (2 << 10)) { /* 2K */
2159 	    inputXSpan = 1;
2160 	    inputXSpanBytes = 2 * 1024;
2161 	}
2162 	else {                             /* 1K */
2163 	    inputXSpan = 0;
2164 	    inputXSpanBytes = 1024;
2165 	}
2166 
2167 	/* compute post multiply */
2168 	binaryEval = realWidthBytes >> 3;
2169 	postMultiply = 0;
2170 	while ((postMultiply < 5) && !(binaryEval & 1)) {
2171 	    postMultiply++;
2172 	    binaryEval >>= 1;
2173 	}
2174 	postMultiply <<= 7;
2175 
2176 	/* compute product enable fields */
2177 	if (binaryEval & ~0x1f) {		/* too big */
2178 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2179 		       "GLINTModeInit: width (%d) too big\n",
2180 		       pScrn->displayWidth);
2181 	    return FALSE;
2182 	}
2183 	if ((binaryEval & 0x12) == 0x12) {	/* clash between x2 and x16 */
2184 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2185 		       "GLINTModeInit: width (%d) is mult 18, not supported\n",
2186 		       pScrn->displayWidth);
2187 	    return FALSE;
2188 	}
2189 	if (binaryEval & 0x10) {
2190 	    productEnable = (((binaryEval & 0xf) | 0x2) << 3);
2191 	    use16xProduct = (1 << 2);
2192 	}
2193 	else {
2194 	    productEnable = ((binaryEval & 0xf) << 3);
2195 	    use16xProduct = 0;
2196 	}
2197 
2198 	/* compute GLINT Aperture Size field */
2199 	binaryEval = ((pScrn->videoRam << 11) - 1);
2200 	if (binaryEval & (32 << 20)) {      /* 32M */
2201 	    glintApSize = 3 << 10;
2202 	}
2203 	else if (binaryEval & (16 << 20)) { /* 16M */
2204 	    glintApSize = 2 << 10;
2205 	}
2206 	else if (binaryEval & (8 << 20)) {  /*  8M */
2207 	    glintApSize = 1 << 10;
2208 	}
2209 	else {                              /*  4M */
2210 	    glintApSize = 0 << 10;
2211 	}
2212 
2213 	pGlint->realWidth = (   glintApSize      |
2214                   	  	postMultiply     |
2215                   		productEnable    |
2216                   		use16xProduct    |
2217                   		inputXSpan       );
2218 
2219 	/* set the MULTI width for software rendering */
2220 	pScrn->displayWidth = inputXSpanBytes / bytesPerPixel;
2221     }
2222 
2223     /* Set the current mode to the first in the list */
2224     pScrn->currentMode = pScrn->modes;
2225 
2226     xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
2227 
2228     /* Print the list of modes being used */
2229     xf86PrintModes(pScrn);
2230 
2231     /* Set display resolution */
2232     xf86SetDpi(pScrn, 0, 0);
2233 
2234     /* Load bpp-specific modules */
2235     switch (pScrn->bitsPerPixel) {
2236     case 8:
2237     case 16:
2238     case 24:
2239 	mod = "fb";
2240 	break;
2241     case 32:
2242 	if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
2243 	    mod = "xf8_32bpp";
2244 	} else {
2245 	    mod = "fb";
2246 	}
2247 	break;
2248     }
2249     if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
2250 	GLINTFreeRec(pScrn);
2251 	return FALSE;
2252     }
2253 
2254     /* Load XAA if needed */
2255     if (!pGlint->NoAccel) {
2256 	if (!xf86LoadSubModule(pScrn, "xaa")) {
2257 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Falling back to shadowfb\n");
2258 	    pGlint->NoAccel = 1;
2259 	    pGlint->ShadowFB = 1;
2260 	}
2261     }
2262 
2263     /* Load shadowfb if needed */
2264     if (pGlint->ShadowFB) {
2265 	if (!xf86LoadSubModule(pScrn, "shadowfb")) {
2266 	    GLINTFreeRec(pScrn);
2267 	    return FALSE;
2268 	}
2269     }
2270 
2271     TRACE_EXIT("GLINTPreInit");
2272     return TRUE;
2273 }
2274 
2275 
2276 /*
2277  * Map the framebuffer and MMIO memory.
2278  */
2279 
2280 static Bool
GLINTMapMem(ScrnInfoPtr pScrn)2281 GLINTMapMem(ScrnInfoPtr pScrn)
2282 {
2283     GLINTPtr pGlint;
2284 
2285     pGlint = GLINTPTR(pScrn);
2286 
2287     TRACE_ENTER("GLINTMapMem");
2288     if (pGlint->FBDev) {
2289     	pGlint->FbBase = fbdevHWMapVidmem(pScrn);
2290     	if (pGlint->FbBase == NULL)
2291 		return FALSE;
2292 
2293     	pGlint->IOBase = fbdevHWMapMMIO(pScrn);
2294     	if (pGlint->IOBase == NULL)
2295 		return FALSE;
2296 
2297 	TRACE_EXIT("GLINTMapMem");
2298 	return TRUE;
2299     }
2300 
2301     /*
2302      * Map IO registers to virtual address space
2303      * We always map VGA IO registers - even if we don't need them
2304      */
2305 #ifndef XSERVER_LIBPCIACCESS
2306     pGlint->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
2307 	       pGlint->PciTag, pGlint->IOAddress, 0x10000);
2308 #else
2309     {
2310       void** result = (void**)&pGlint->IOBase;
2311       int err = pci_device_map_range(pGlint->PciInfo,
2312 				     pGlint->IOAddress,
2313 				     0x10000,
2314 				     PCI_DEV_MAP_FLAG_WRITABLE,
2315 				     result);
2316 
2317       if (err)
2318 	return FALSE;
2319     }
2320 #endif
2321 
2322     if (pGlint->IOBase == NULL)
2323 	return FALSE;
2324 
2325     if (pGlint->FbMapSize != 0) {
2326 #ifndef XSERVER_LIBPCIACCESS
2327     	pGlint->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
2328 				 pGlint->PciTag,
2329 				 pGlint->FbAddress,
2330 				 pGlint->FbMapSize);
2331 #else
2332 	{
2333 	  void** result = (void**)&pGlint->FbBase;
2334 	  int err = pci_device_map_range(pGlint->PciInfo,
2335 					 pGlint->FbAddress,
2336 					 pGlint->FbMapSize,
2337 					 PCI_DEV_MAP_FLAG_WRITABLE |
2338 					 PCI_DEV_MAP_FLAG_WRITE_COMBINE,
2339 					 result);
2340 
2341 	  if (err)
2342 	    return FALSE;
2343 	}
2344 
2345 #endif
2346         if (pGlint->FbBase == NULL)
2347 	    return FALSE;
2348     }
2349 
2350     TRACE_EXIT("GLINTMapMem");
2351     return TRUE;
2352 }
2353 
2354 
2355 /*
2356  * Unmap the framebuffer and MMIO memory.
2357  */
2358 
2359 static Bool
GLINTUnmapMem(ScrnInfoPtr pScrn)2360 GLINTUnmapMem(ScrnInfoPtr pScrn)
2361 {
2362     GLINTPtr pGlint;
2363 
2364     pGlint = GLINTPTR(pScrn);
2365 
2366     TRACE_ENTER("GLINTUnmapMem");
2367     if (pGlint->FBDev) {
2368     	fbdevHWUnmapVidmem(pScrn);
2369     	pGlint->FbBase = NULL;
2370     	fbdevHWUnmapMMIO(pScrn);
2371     	pGlint->IOBase = NULL;
2372 
2373 	TRACE_EXIT("GLINTUnmapMem");
2374     	return TRUE;
2375     }
2376 
2377     /*
2378      * Unmap IO registers to virtual address space
2379      */
2380 #ifndef XSERVER_LIBPCIACCESS
2381     xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pGlint->IOBase, 0x10000);
2382 #else
2383     pci_device_unmap_range(pGlint->PciInfo, pGlint->IOBase, 0x10000);
2384 #endif
2385     pGlint->IOBase = NULL;
2386 
2387     if (pGlint->FbBase != NULL) {
2388 #ifndef XSERVER_LIBPCIACCESS
2389     	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pGlint->FbBase, pGlint->FbMapSize);
2390 #else
2391 	pci_device_unmap_range(pGlint->PciInfo, pGlint->FbBase, pGlint->FbMapSize);
2392 #endif
2393     }
2394     pGlint->FbBase = NULL;
2395 
2396     TRACE_EXIT("GLINTUnmapMem");
2397     return TRUE;
2398 }
2399 
2400 /*
2401  * This function saves the video state.
2402  */
2403 static void
GLINTSave(ScrnInfoPtr pScrn)2404 GLINTSave(ScrnInfoPtr pScrn)
2405 {
2406     GLINTPtr pGlint;
2407     GLINTRegPtr glintReg;
2408     GLINTRegPtr glintReg2;
2409     RamDacHWRecPtr pRAMDAC;
2410     RamDacRegRecPtr RAMDACreg;
2411 
2412     pGlint = GLINTPTR(pScrn);
2413     pRAMDAC = RAMDACHWPTR(pScrn);
2414     glintReg = &pGlint->SavedReg[0];
2415     glintReg2 = &pGlint->SavedReg[1];
2416     RAMDACreg = &pRAMDAC->SavedReg;
2417     TRACE_ENTER("GLINTSave");
2418 
2419     switch (pGlint->Chipset)
2420     {
2421     case PCI_VENDOR_TI_CHIP_PERMEDIA2:
2422     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
2423 	Permedia2Save(pScrn, glintReg);
2424 	break;
2425     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
2426 	Permedia2VSave(pScrn, glintReg);
2427 	break;
2428     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
2429     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
2430     case PCI_VENDOR_3DLABS_CHIP_R4:
2431 	Permedia3Save(pScrn, glintReg);
2432 	break;
2433     case PCI_VENDOR_TI_CHIP_PERMEDIA:
2434     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
2435 	PermediaSave(pScrn, glintReg);
2436 	(*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg);
2437 	break;
2438     case PCI_VENDOR_3DLABS_CHIP_500TX:
2439     case PCI_VENDOR_3DLABS_CHIP_300SX:
2440     case PCI_VENDOR_3DLABS_CHIP_MX:
2441 	TXSave(pScrn, glintReg);
2442 	(*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg);
2443 	break;
2444     case PCI_VENDOR_3DLABS_CHIP_GAMMA:
2445     case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
2446     case PCI_VENDOR_3DLABS_CHIP_DELTA:
2447 	switch (pGlint->MultiChip) {
2448 	case PCI_CHIP_3DLABS_500TX:
2449 	case PCI_CHIP_3DLABS_300SX:
2450 	case PCI_CHIP_3DLABS_MX:
2451 	    if (pGlint->numMultiDevices == 2) {
2452 		ACCESSCHIP2()
2453 	    	TXSave(pScrn, glintReg2);
2454 #if 0
2455 	    	(*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg2);
2456 #endif
2457 	    	ACCESSCHIP1();
2458 	    }
2459 	    TXSave(pScrn, glintReg);
2460 	    (*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg);
2461 	    break;
2462     	case PCI_CHIP_3DLABS_PERMEDIA:
2463     	case PCI_CHIP_TI_PERMEDIA:
2464 	    PermediaSave(pScrn, glintReg);
2465 	    (*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg);
2466 	    break;
2467 	case PCI_CHIP_3DLABS_R4:
2468 	case PCI_CHIP_3DLABS_PERMEDIA3:
2469 	    if (pGlint->numMultiDevices == 2) {
2470 		ACCESSCHIP2();
2471 	    	Permedia3Save(pScrn, glintReg2);
2472 		ACCESSCHIP1();
2473 	    }
2474 	    Permedia3Save(pScrn, glintReg);
2475 	    break;
2476 	}
2477 	break;
2478     }
2479     TRACE_EXIT("GLINTSave");
2480 }
2481 
2482 
2483 /*
2484  * Initialise a new mode.  This is currently still using the old
2485  * "initialise struct, restore/write struct to HW" model.  That could
2486  * be changed.
2487  */
2488 
2489 static Bool
GLINTModeInit(ScrnInfoPtr pScrn,DisplayModePtr mode)2490 GLINTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
2491 {
2492     int ret = -1;
2493     GLINTPtr pGlint = GLINTPTR(pScrn);
2494     RamDacHWRecPtr pRAMDAC = RAMDACHWPTR(pScrn);
2495     RamDacRegRecPtr RAMDACreg;
2496     GLINTRegPtr glintReg = &pGlint->ModeReg[0];
2497     GLINTRegPtr glintReg2 = &pGlint->ModeReg[1];
2498 
2499     pScrn->vtSema = TRUE;
2500 
2501     switch (pGlint->Chipset) {
2502     case PCI_VENDOR_TI_CHIP_PERMEDIA2:
2503     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
2504 	ret = Permedia2Init(pScrn, mode);
2505 	break;
2506     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
2507 	ret = Permedia2VInit(pScrn, mode);
2508 	break;
2509     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
2510     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
2511     case PCI_VENDOR_3DLABS_CHIP_R4:
2512 	ret = Permedia3Init(pScrn, mode, glintReg);
2513 	break;
2514     case PCI_VENDOR_TI_CHIP_PERMEDIA:
2515     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
2516 	ret = PermediaInit(pScrn, mode);
2517 	break;
2518     case PCI_VENDOR_3DLABS_CHIP_500TX:
2519     case PCI_VENDOR_3DLABS_CHIP_300SX:
2520     case PCI_VENDOR_3DLABS_CHIP_MX:
2521 	ret = TXInit(pScrn, mode, glintReg);
2522 	break;
2523     case PCI_VENDOR_3DLABS_CHIP_GAMMA:
2524     case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
2525     case PCI_VENDOR_3DLABS_CHIP_DELTA:
2526 	switch (pGlint->MultiChip) {
2527 	case PCI_CHIP_3DLABS_MX:
2528 	case PCI_CHIP_3DLABS_500TX:
2529 	case PCI_CHIP_3DLABS_300SX:
2530 	    if (pGlint->numMultiDevices == 2) {
2531 		ACCESSCHIP2();
2532 	    	ret = TXInit(pScrn, mode, glintReg2);
2533 	    	ACCESSCHIP1();
2534 	    }
2535 	    ret = TXInit(pScrn, mode, glintReg);
2536 	    break;
2537 	case PCI_CHIP_3DLABS_PERMEDIA:
2538 	case PCI_CHIP_TI_PERMEDIA:
2539 	    ret = PermediaInit(pScrn, mode);
2540 	    break;
2541 	case PCI_CHIP_3DLABS_R4:
2542 	case PCI_CHIP_3DLABS_PERMEDIA3:
2543 	    if (pGlint->numMultiDevices == 2) {
2544 		ACCESSCHIP2();
2545 	    	ret = Permedia3Init(pScrn, mode, glintReg2);
2546 	    	ACCESSCHIP1();
2547 	    }
2548 	    ret = Permedia3Init(pScrn, mode, glintReg);
2549 	    break;
2550 	}
2551 	break;
2552     }
2553 
2554     if (!ret)
2555 	return FALSE;
2556 
2557     glintReg = &pGlint->ModeReg[0];
2558     glintReg2 = &pGlint->ModeReg[1];
2559     RAMDACreg = &pRAMDAC->ModeReg;
2560 
2561     pGlint->STATE = FALSE;
2562 
2563     switch (pGlint->Chipset) {
2564     case PCI_VENDOR_TI_CHIP_PERMEDIA2:
2565     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
2566 	Permedia2Restore(pScrn, glintReg);
2567 	break;
2568     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
2569 	Permedia2VRestore(pScrn, glintReg);
2570 	break;
2571     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
2572     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
2573     case PCI_VENDOR_3DLABS_CHIP_R4:
2574 	Permedia3Restore(pScrn, glintReg);
2575 	break;
2576     case PCI_VENDOR_TI_CHIP_PERMEDIA:
2577     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
2578 	PermediaRestore(pScrn, glintReg);
2579 	(*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg);
2580 	break;
2581     case PCI_VENDOR_3DLABS_CHIP_500TX:
2582     case PCI_VENDOR_3DLABS_CHIP_300SX:
2583     case PCI_VENDOR_3DLABS_CHIP_MX:
2584 	TXRestore(pScrn, glintReg);
2585 	(*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg);
2586 	break;
2587     case PCI_VENDOR_3DLABS_CHIP_GAMMA:
2588     case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
2589     case PCI_VENDOR_3DLABS_CHIP_DELTA:
2590 	switch (pGlint->MultiChip) {
2591 	case PCI_CHIP_3DLABS_500TX:
2592 	case PCI_CHIP_3DLABS_300SX:
2593 	case PCI_CHIP_3DLABS_MX:
2594 	    if (pGlint->numMultiDevices == 2) {
2595 		ACCESSCHIP2();
2596 	    	TXRestore(pScrn, glintReg2);
2597 #if 0
2598 	    	(*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec,RAMDACreg2);
2599 #endif
2600 	    	ACCESSCHIP1();
2601 	    }
2602 	    TXRestore(pScrn, glintReg);
2603 	    (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg);
2604 	    break;
2605 	case PCI_CHIP_3DLABS_PERMEDIA:
2606 	case PCI_CHIP_TI_PERMEDIA:
2607 	    PermediaRestore(pScrn, glintReg);
2608 	    (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg);
2609 	    break;
2610 	case PCI_CHIP_3DLABS_R4:
2611 	case PCI_CHIP_3DLABS_PERMEDIA3:
2612 	    if (pGlint->numMultiDevices == 2) {
2613 		ACCESSCHIP2();
2614 	    	Permedia3Restore(pScrn, glintReg2);
2615 		ACCESSCHIP1();
2616 	    }
2617 	    Permedia3Restore(pScrn, glintReg);
2618 	    break;
2619 	}
2620 	break;
2621     }
2622 
2623 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
2624     if (xf86IsPc98())
2625        outb(0xfac, 0x01);
2626 #endif
2627 
2628     return TRUE;
2629 }
2630 
2631 /*
2632  * Restore the initial (text) mode.
2633  */
2634 static void
GLINTRestore(ScrnInfoPtr pScrn)2635 GLINTRestore(ScrnInfoPtr pScrn)
2636 {
2637     GLINTPtr pGlint;
2638     GLINTRegPtr glintReg;
2639     GLINTRegPtr glintReg2;
2640     RamDacHWRecPtr pRAMDAC;
2641     RamDacRegRecPtr RAMDACreg;
2642 
2643     pGlint = GLINTPTR(pScrn);
2644     pRAMDAC = RAMDACHWPTR(pScrn);
2645     glintReg = &pGlint->SavedReg[0];
2646     glintReg2 = &pGlint->SavedReg[1];
2647     RAMDACreg = &pRAMDAC->SavedReg;
2648 
2649     TRACE_ENTER("GLINTRestore");
2650 
2651     switch (pGlint->Chipset) {
2652     case PCI_VENDOR_TI_CHIP_PERMEDIA2:
2653     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
2654 	Permedia2VideoLeaveVT(pScrn);
2655 	Permedia2Restore(pScrn, glintReg);
2656 	break;
2657     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
2658 	Permedia2VideoLeaveVT(pScrn);
2659 	Permedia2VRestore(pScrn, glintReg);
2660 	break;
2661     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
2662     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
2663     case PCI_VENDOR_3DLABS_CHIP_R4:
2664 	Permedia3Restore(pScrn, glintReg);
2665 	break;
2666     case PCI_VENDOR_TI_CHIP_PERMEDIA:
2667     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
2668 	PermediaRestore(pScrn, glintReg);
2669 	(*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg);
2670 	break;
2671     case PCI_VENDOR_3DLABS_CHIP_500TX:
2672     case PCI_VENDOR_3DLABS_CHIP_300SX:
2673     case PCI_VENDOR_3DLABS_CHIP_MX:
2674 	TXRestore(pScrn, glintReg);
2675 	(*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg);
2676 	break;
2677     case PCI_VENDOR_3DLABS_CHIP_GAMMA:
2678     case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
2679     case PCI_VENDOR_3DLABS_CHIP_DELTA:
2680 	switch (pGlint->MultiChip) {
2681 	case PCI_CHIP_3DLABS_MX:
2682 	case PCI_CHIP_3DLABS_500TX:
2683 	case PCI_CHIP_3DLABS_300SX:
2684 	    if (pGlint->numMultiDevices == 2) {
2685 	    	ACCESSCHIP2();
2686 	    	TXRestore(pScrn, glintReg2);
2687 #if 0
2688 	    	(*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec,RAMDACreg2);
2689 #endif
2690 	    	ACCESSCHIP1();
2691 	    }
2692 	    TXRestore(pScrn, glintReg);
2693 	    (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg);
2694 	    break;
2695     	case PCI_CHIP_3DLABS_PERMEDIA:
2696     	case PCI_CHIP_TI_PERMEDIA:
2697 	    PermediaRestore(pScrn, glintReg);
2698 	    (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg);
2699 	    break;
2700 	case PCI_CHIP_3DLABS_R4:
2701 	case PCI_CHIP_3DLABS_PERMEDIA3:
2702 	    if (pGlint->numMultiDevices == 2) {
2703 		ACCESSCHIP2();
2704 	    	Permedia3Restore(pScrn, glintReg2);
2705 		ACCESSCHIP1();
2706 	    }
2707 	    Permedia3Restore(pScrn, glintReg);
2708 	    break;
2709 	}
2710 	break;
2711     }
2712 
2713     TRACE_EXIT("GLINTRestore");
2714 }
2715 
2716 
2717 /* Mandatory */
2718 
2719 /* This gets called at the start of each server generation */
2720 
2721 static Bool
GLINTScreenInit(SCREEN_INIT_ARGS_DECL)2722 GLINTScreenInit(SCREEN_INIT_ARGS_DECL)
2723 {
2724     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
2725     GLINTPtr pGlint = GLINTPTR(pScrn);
2726     int ret, displayWidth;
2727     unsigned char *FBStart;
2728     VisualPtr visual;
2729 
2730     TRACE_ENTER("GLINTScreenInit");
2731     /* Map the GLINT memory and MMIO areas */
2732     if (!GLINTMapMem(pScrn))
2733 	return FALSE;
2734 
2735     if (pGlint->FBDev) {
2736 	fbdevHWSave(pScrn);
2737  	if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) {
2738 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2739 		   "Internal error: invalid mode\n");
2740 		return FALSE;
2741 	}
2742     } else
2743     /* Save the current state */
2744     GLINTSave(pScrn);
2745 
2746     /* Initialise the first mode */
2747     if ( (!pGlint->FBDev) && !(GLINTModeInit(pScrn, pScrn->currentMode))) {
2748 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2749 		   "Internal error: invalid mode\n");
2750 	return FALSE;
2751     }
2752 
2753     /* Darken the screen for aesthetic reasons and set the viewport */
2754     GLINTSaveScreen(pScreen, SCREEN_SAVER_ON);
2755     GLINTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
2756 
2757     /*
2758      * The next step is to setup the screen's visuals, and initialise the
2759      * framebuffer code.  In cases where the framebuffer's default
2760      * choices for things like visual layouts and bits per RGB are OK,
2761      * this may be as simple as calling the framebuffer's ScreenInit()
2762      * function.  If not, the visuals will need to be setup before calling
2763      * a fb ScreenInit() function and fixed up after.
2764      *
2765      * For most PC hardware at depths >= 8, the defaults that cfb uses
2766      * are not appropriate.  In this driver, we fixup the visuals after.
2767      */
2768 
2769     /*
2770      * Reset visual list.
2771      */
2772     miClearVisualTypes();
2773 
2774     /* Setup the visuals we support. */
2775 
2776     /*
2777      * For bpp > 8, the default visuals are not acceptable because we only
2778      * support TrueColor and not DirectColor.  To deal with this, call
2779      * miSetVisualTypes for each visual supported.
2780      */
2781 
2782     if((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
2783 						(pScrn->bitsPerPixel == 32)) {
2784 	if (!miSetVisualTypes(8, PseudoColorMask | GrayScaleMask,
2785 			      pScrn->rgbBits, PseudoColor))
2786 		return FALSE;
2787 	if (!miSetVisualTypes(24, TrueColorMask, pScrn->rgbBits, TrueColor))
2788 		return FALSE;
2789     } else {
2790 	if (!miSetVisualTypes(pScrn->depth,
2791 			      miGetDefaultVisualMask(pScrn->depth),
2792 			      pScrn->rgbBits, pScrn->defaultVisual))
2793 	    return FALSE;
2794 	if (!miSetPixmapDepths())
2795 	    return FALSE;
2796     }
2797 
2798     /*
2799      * Call the framebuffer layer's ScreenInit function, and fill in other
2800      * pScreen fields.
2801      */
2802 
2803     if(pGlint->ShadowFB) {
2804  	pGlint->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * pScrn->virtualX);
2805         pGlint->ShadowPtr = malloc(pGlint->ShadowPitch * pScrn->virtualY);
2806 	displayWidth = pGlint->ShadowPitch / (pScrn->bitsPerPixel >> 3);
2807         FBStart = pGlint->ShadowPtr;
2808     } else {
2809 	pGlint->ShadowPtr = NULL;
2810 	displayWidth = pScrn->displayWidth;
2811 	FBStart = pGlint->FbBase;
2812     }
2813 
2814     switch (pScrn->bitsPerPixel) {
2815     case 8:
2816     case 16:
2817     case 24:
2818     case 32:
2819 	ret = fbScreenInit(pScreen, FBStart,
2820 			pScrn->virtualX, pScrn->virtualY,
2821 			pScrn->xDpi, pScrn->yDpi,
2822 			displayWidth, pScrn->bitsPerPixel);
2823 	break;
2824     default:
2825 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2826 		   "Internal error: invalid bpp (%d) in GLINTScrnInit\n",
2827 		   pScrn->bitsPerPixel);
2828 	    ret = FALSE;
2829 	break;
2830     }
2831     if (!ret)
2832 	return FALSE;
2833 
2834     xf86SetBlackWhitePixels(pScreen);
2835 
2836     pGlint->BlockHandler = pScreen->BlockHandler;
2837     pScreen->BlockHandler = GLINTBlockHandler;
2838 
2839 #if !defined(__sparc__)
2840     if (!pGlint->ShadowFB)
2841 	GLINTDGAInit(pScreen);
2842 #endif
2843 
2844     if (pScrn->bitsPerPixel > 8) {
2845         /* Fixup RGB ordering */
2846         visual = pScreen->visuals + pScreen->numVisuals;
2847         while (--visual >= pScreen->visuals) {
2848 	    if ((visual->class | DynamicClass) == DirectColor) {
2849 		visual->offsetRed = pScrn->offset.red;
2850 		visual->offsetGreen = pScrn->offset.green;
2851 		visual->offsetBlue = pScrn->offset.blue;
2852 		visual->redMask = pScrn->mask.red;
2853 		visual->greenMask = pScrn->mask.green;
2854 		visual->blueMask = pScrn->mask.blue;
2855 	    }
2856 	}
2857     }
2858 
2859     /* must be after RGB ordering fixed */
2860     fbPictureInit(pScreen, 0, 0);
2861     if (!pGlint->NoAccel) {
2862         switch (pGlint->Chipset)
2863         {
2864         case PCI_VENDOR_TI_CHIP_PERMEDIA2:
2865         case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
2866         case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
2867 	    Permedia2AccelInit(pScreen);
2868 	    break;
2869 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
2870 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
2871 	case PCI_VENDOR_3DLABS_CHIP_R4:
2872 	    Permedia3AccelInit(pScreen);
2873 	    break;
2874 	case PCI_VENDOR_TI_CHIP_PERMEDIA:
2875 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
2876 	    PermediaAccelInit(pScreen);
2877 	    break;
2878 	case PCI_VENDOR_3DLABS_CHIP_500TX:
2879 	case PCI_VENDOR_3DLABS_CHIP_MX:
2880 	    TXAccelInit(pScreen);
2881 	    break;
2882 	case PCI_VENDOR_3DLABS_CHIP_GAMMA:
2883 	case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
2884 	case PCI_VENDOR_3DLABS_CHIP_DELTA:
2885 	    switch (pGlint->MultiChip) {
2886 	    case PCI_CHIP_3DLABS_500TX:
2887 	    case PCI_CHIP_3DLABS_MX:
2888 		TXAccelInit(pScreen);
2889 		break;
2890 	    case PCI_CHIP_3DLABS_300SX:
2891 		SXAccelInit(pScreen);
2892 		break;
2893 	    case PCI_CHIP_3DLABS_PERMEDIA:
2894 	    case PCI_CHIP_TI_PERMEDIA:
2895 	        PermediaAccelInit(pScreen);
2896 	        break;
2897 	    case PCI_CHIP_3DLABS_R4:
2898 	    case PCI_CHIP_3DLABS_PERMEDIA3:
2899 		Permedia3AccelInit(pScreen);
2900 		break;
2901 	    }
2902 	    break;
2903 	case PCI_VENDOR_3DLABS_CHIP_300SX:
2904 	    SXAccelInit(pScreen);
2905 	    break;
2906         }
2907     }
2908 
2909     xf86SetBackingStore(pScreen);
2910     xf86SetSilkenMouse(pScreen);
2911 
2912     miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
2913 
2914     /* Initialise cursor functions */
2915     if (pGlint->HWCursor) {
2916 	/* Handle VGA chipsets first */
2917 	if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) ||
2918 	    (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2))
2919 	    Permedia2HWCursorInit(pScreen);
2920 	else
2921 	if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) ||
2922 	    (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) ||
2923 	    (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) ||
2924 	    (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_R4) ||
2925 	    ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA2) &&
2926 	     (pGlint->MultiChip == PCI_CHIP_3DLABS_R4)) ||
2927 	    ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
2928 	     (pGlint->MultiChip == PCI_CHIP_3DLABS_PERMEDIA3)) )
2929 	    Permedia2vHWCursorInit(pScreen);
2930 	else
2931 	/* If we get here pGlint->Ramdac should have been set */
2932 	if ( ((pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC)) ||
2933 	      (pGlint->RamDac->RamDacType == (IBM526_RAMDAC)) ||
2934 	      (pGlint->RamDac->RamDacType == (IBM640_RAMDAC))) )
2935 	    		glintIBMHWCursorInit(pScreen);
2936 	else
2937 	if ( (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) ||
2938 	     (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) )
2939 	    		glintTIHWCursorInit(pScreen);
2940     }
2941 
2942     /* Initialise default colourmap */
2943     if (!miCreateDefColormap(pScreen))
2944 	return FALSE;
2945 
2946     if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) ||
2947 	(pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA4) ||
2948 	(pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_R4) ||
2949 	((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA2) &&
2950 	 (pGlint->MultiChip == PCI_CHIP_3DLABS_R4)) ||
2951 	((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
2952 	 (pGlint->MultiChip == PCI_CHIP_3DLABS_PERMEDIA3)) ) {
2953     	if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,
2954 	    (pGlint->FBDev) ? fbdevHWLoadPaletteWeak() :
2955 	    ((pScrn->depth == 16) ? Permedia3LoadPalette16:Permedia3LoadPalette),
2956 	    NULL,
2957 	    CMAP_RELOAD_ON_MODE_SWITCH |
2958 	    ((pScrn->overlayFlags & OVERLAY_8_32_PLANAR)
2959 					? 0 : CMAP_PALETTED_TRUECOLOR)))
2960 	return FALSE;
2961     } else
2962     if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) ||
2963 	(pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) ||
2964 	(pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2)) {
2965     	if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,
2966 	    (pGlint->FBDev) ? fbdevHWLoadPaletteWeak() :
2967 	    ((pScrn->depth == 16) ? Permedia2LoadPalette16:Permedia2LoadPalette),
2968 	    NULL,
2969 	    CMAP_RELOAD_ON_MODE_SWITCH |
2970 	    ((pScrn->overlayFlags & OVERLAY_8_32_PLANAR)
2971 					? 0 : CMAP_PALETTED_TRUECOLOR)))
2972 	return FALSE;
2973     } else {
2974 	if (pScrn->rgbBits == 10) {
2975     	if (!RamDacHandleColormaps(pScreen, 1024, pScrn->rgbBits,
2976 	    CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
2977 	return FALSE;
2978 	} else {
2979     	if (!RamDacHandleColormaps(pScreen, 256, pScrn->rgbBits,
2980 	    CMAP_RELOAD_ON_MODE_SWITCH |
2981 	    ((pScrn->overlayFlags & OVERLAY_8_32_PLANAR)
2982 					? 0 : CMAP_PALETTED_TRUECOLOR)))
2983 	return FALSE;
2984 	}
2985     }
2986 
2987     if(pGlint->ShadowFB)
2988 	ShadowFBInit(pScreen, GLINTRefreshArea);
2989 
2990     xf86DPMSInit(pScreen, (DPMSSetProcPtr)GLINTDisplayPowerManagementSet, 0);
2991 
2992     pScrn->memPhysBase = pGlint->FbAddress;
2993     pScrn->fbOffset = 0;
2994 
2995     pGlint->CloseScreen = pScreen->CloseScreen;
2996     pScreen->CloseScreen = GLINTCloseScreen;
2997     pScreen->SaveScreen = GLINTSaveScreen;
2998 
2999     /* Report any unused options (only for the first generation) */
3000     if (serverGeneration == 1) {
3001 	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
3002     }
3003 
3004     switch (pGlint->Chipset) {
3005         case PCI_VENDOR_TI_CHIP_PERMEDIA2:
3006         case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
3007         case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
3008 	    Permedia2VideoInit(pScreen);
3009 	    break;
3010         case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
3011         case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
3012 	case PCI_VENDOR_3DLABS_CHIP_R4:
3013 	    Permedia3InitVideo(pScreen);
3014 	    break;
3015 	case PCI_VENDOR_3DLABS_CHIP_GAMMA:
3016 	case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
3017 	    switch (pGlint->MultiChip) {
3018 		case PCI_CHIP_3DLABS_R4:
3019 		case PCI_CHIP_3DLABS_PERMEDIA3:
3020 		    Permedia3InitVideo(pScreen);
3021 	    }
3022     }
3023 
3024 #if 0
3025     /* Enable the screen */
3026     GLINTSaveScreen(pScreen, SCREEN_SAVER_OFF);
3027 #endif
3028 
3029     /* Done */
3030     TRACE_EXIT("GLINTScreenInit");
3031     return TRUE;
3032 }
3033 
3034 /* Usually mandatory */
3035 Bool
GLINTSwitchMode(SWITCH_MODE_ARGS_DECL)3036 GLINTSwitchMode(SWITCH_MODE_ARGS_DECL)
3037 {
3038     SCRN_INFO_PTR(arg);
3039     GLINTPtr pGlint;
3040 
3041     pGlint = GLINTPTR(pScrn);
3042     TRACE_ENTER("GLINTSwitchMode");
3043 
3044     if (pGlint->FBDev) {
3045 	Bool ret = fbdevHWSwitchMode(SWITCH_MODE_ARGS(pScrn, mode));
3046 
3047 	if (!pGlint->NoAccel) {
3048     	    switch (pGlint->Chipset) {
3049     		case PCI_VENDOR_TI_CHIP_PERMEDIA2:
3050     		case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
3051     		case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
3052 			Permedia2InitializeEngine(pScrn);
3053 			break;
3054     		case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
3055     		case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
3056 		case PCI_VENDOR_3DLABS_CHIP_R4:
3057 			Permedia3InitializeEngine(pScrn);
3058 			break;
3059     		case PCI_VENDOR_TI_CHIP_PERMEDIA:
3060     		case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
3061 			PermediaInitializeEngine(pScrn);
3062 			break;
3063     		case PCI_VENDOR_3DLABS_CHIP_500TX:
3064     		case PCI_VENDOR_3DLABS_CHIP_MX:
3065 	    		TXInitializeEngine(pScrn);
3066 			break;
3067     		case PCI_VENDOR_3DLABS_CHIP_300SX:
3068 	    		SXInitializeEngine(pScrn);
3069 			break;
3070     		case PCI_VENDOR_3DLABS_CHIP_GAMMA:
3071     		case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
3072     		case PCI_VENDOR_3DLABS_CHIP_DELTA:
3073 			switch (pGlint->MultiChip) {
3074 			case PCI_CHIP_3DLABS_500TX:
3075 			case PCI_CHIP_3DLABS_MX:
3076 	    		    TXInitializeEngine(pScrn);
3077 			    break;
3078 			case PCI_CHIP_3DLABS_300SX:
3079 	    		    SXInitializeEngine(pScrn);
3080 			    break;
3081 			case PCI_CHIP_3DLABS_PERMEDIA:
3082 			case PCI_CHIP_TI_PERMEDIA:
3083 	    		    PermediaInitializeEngine(pScrn);
3084 			    break;
3085 			case PCI_CHIP_3DLABS_R4:
3086 			case PCI_CHIP_3DLABS_PERMEDIA3:
3087 	    		    Permedia3InitializeEngine(pScrn);
3088 			    break;
3089 			}
3090 			break;
3091     	    }
3092 	}
3093 
3094 	TRACE_EXIT("GLINTSwitchMode (fbdev ?)");
3095 	return ret;
3096     }
3097 
3098     TRACE_EXIT("GLINTSwitchMode (normal)");
3099     return GLINTModeInit(pScrn, mode);
3100 }
3101 
3102 
3103 /*
3104  * This function is used to initialize the Start Address - the first
3105  * displayed location in the video memory.
3106  */
3107 /* Usually mandatory */
3108 void
GLINTAdjustFrame(ADJUST_FRAME_ARGS_DECL)3109 GLINTAdjustFrame(ADJUST_FRAME_ARGS_DECL)
3110 {
3111     SCRN_INFO_PTR(arg);
3112     CARD32 base;
3113     GLINTPtr pGlint;
3114 
3115     pGlint = GLINTPTR(pScrn);
3116     TRACE_ENTER("GLINTAdjustFrame");
3117 
3118     if (pGlint->FBDev) {
3119     	fbdevHWAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y));
3120 	TRACE_EXIT("GLINTAdjustFrame (fbdev)");
3121 	return;
3122     }
3123 
3124     base = ((y * pScrn->displayWidth + x) >> 1) >> pGlint->BppShift;
3125     if (pScrn->bitsPerPixel == 24) base *= 3;
3126 
3127     switch (pGlint->Chipset)
3128     {
3129     case PCI_VENDOR_TI_CHIP_PERMEDIA:
3130     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
3131     case PCI_VENDOR_TI_CHIP_PERMEDIA2:
3132     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
3133     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
3134 	GLINT_SLOW_WRITE_REG(base, PMScreenBase);
3135 	break;
3136     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
3137     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
3138     case PCI_VENDOR_3DLABS_CHIP_R4:
3139     	base = (y * pScrn->displayWidth + x) >> pGlint->BppShift;
3140 	GLINT_SLOW_WRITE_REG(base, PMScreenBase);
3141 	break;
3142     case PCI_VENDOR_3DLABS_CHIP_GAMMA:
3143     case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
3144     case PCI_VENDOR_3DLABS_CHIP_DELTA:
3145 	switch (pGlint->MultiChip) {
3146 	case PCI_CHIP_3DLABS_R4:
3147 	case PCI_CHIP_3DLABS_PERMEDIA3:
3148     	    base = (y * pScrn->displayWidth + x)  >> pGlint->BppShift;
3149 	    GLINT_SLOW_WRITE_REG(base, PMScreenBase);
3150 	    break;
3151 	case PCI_CHIP_3DLABS_PERMEDIA:
3152 	case PCI_CHIP_TI_PERMEDIA:
3153 	    GLINT_SLOW_WRITE_REG(base, PMScreenBase);
3154 	    break;
3155 	}
3156 	break;
3157     }
3158     TRACE_EXIT("GLINTAdjustFrame (normal)");
3159 }
3160 
3161 
3162 /*
3163  * This is called when VT switching back to the X server.  Its job is
3164  * to reinitialise the video mode.
3165  *
3166  * We may wish to unmap video/MMIO memory too.
3167  */
3168 
3169 /* Mandatory */
3170 static Bool
GLINTEnterVT(VT_FUNC_ARGS_DECL)3171 GLINTEnterVT(VT_FUNC_ARGS_DECL)
3172 {
3173     SCRN_INFO_PTR(arg);
3174     GLINTPtr pGlint = GLINTPTR(pScrn);
3175 
3176     TRACE_ENTER("GLINTEnterVT");
3177 
3178     if (pGlint->FBDev)
3179     	fbdevHWEnterVT(VT_FUNC_ARGS);
3180     else
3181     	/* Should we re-save the text mode on each VT enter? */
3182     	if (!GLINTModeInit(pScrn, pScrn->currentMode))
3183 		return FALSE;
3184 
3185     switch (pGlint->Chipset) {
3186     case PCI_VENDOR_TI_CHIP_PERMEDIA2:
3187     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
3188     case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
3189 	Permedia2VideoEnterVT(pScrn);
3190 	break;
3191     }
3192 
3193     if (!pGlint->NoAccel) {
3194     	switch (pGlint->Chipset) {
3195     	case PCI_VENDOR_TI_CHIP_PERMEDIA2:
3196     	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
3197     	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
3198 		Permedia2InitializeEngine(pScrn);
3199 		break;
3200     	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
3201     	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
3202 	case PCI_VENDOR_3DLABS_CHIP_R4:
3203 		Permedia3InitializeEngine(pScrn);
3204 		break;
3205     	case PCI_VENDOR_TI_CHIP_PERMEDIA:
3206     	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
3207 		PermediaInitializeEngine(pScrn);
3208 		break;
3209     	case PCI_VENDOR_3DLABS_CHIP_500TX:
3210     	case PCI_VENDOR_3DLABS_CHIP_MX:
3211 	   	TXInitializeEngine(pScrn);
3212 		break;
3213     	case PCI_VENDOR_3DLABS_CHIP_300SX:
3214 	   	SXInitializeEngine(pScrn);
3215 		break;
3216     	case PCI_VENDOR_3DLABS_CHIP_GAMMA:
3217     	case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
3218     	case PCI_VENDOR_3DLABS_CHIP_DELTA:
3219 		switch (pGlint->MultiChip) {
3220 		case PCI_CHIP_3DLABS_500TX:
3221 		case PCI_CHIP_3DLABS_MX:
3222 	    	    TXInitializeEngine(pScrn);
3223 		    break;
3224 		case PCI_CHIP_3DLABS_300SX:
3225 	    	    SXInitializeEngine(pScrn);
3226 		    break;
3227 		case PCI_CHIP_3DLABS_PERMEDIA:
3228 		case PCI_CHIP_TI_PERMEDIA:
3229 	    	    PermediaInitializeEngine(pScrn);
3230 		    break;
3231 		case PCI_CHIP_3DLABS_R4:
3232 		case PCI_CHIP_3DLABS_PERMEDIA3:
3233 	    	    Permedia3InitializeEngine(pScrn);
3234 		    break;
3235 		}
3236 		break;
3237     	}
3238     }
3239 
3240     TRACE_EXIT("GLINTEnterVTFBDev");
3241     return TRUE;
3242 }
3243 
3244 
3245 /*
3246  * This is called when VT switching away from the X server.  Its job is
3247  * to restore the previous (text) mode.
3248  *
3249  * We may wish to remap video/MMIO memory too.
3250  */
3251 
3252 /* Mandatory */
3253 static void
GLINTLeaveVT(VT_FUNC_ARGS_DECL)3254 GLINTLeaveVT(VT_FUNC_ARGS_DECL)
3255 {
3256     SCRN_INFO_PTR(arg);
3257     GLINTPtr pGlint = GLINTPTR(pScrn);
3258 
3259     TRACE_ENTER("GLINTLeaveVT");
3260     pGlint->STATE = TRUE;
3261     GLINTRestore(pScrn);
3262 
3263 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
3264     if (xf86IsPc98())
3265        outb(0xfac, 0x00);
3266 #endif
3267 
3268     TRACE_EXIT("GLINTLeaveVT");
3269 }
3270 
3271 
3272 /*
3273  * This is called at the end of each server generation.  It restores the
3274  * original (text) mode.  It should really also unmap the video memory too.
3275  */
3276 
3277 /* Mandatory */
3278 static Bool
GLINTCloseScreen(CLOSE_SCREEN_ARGS_DECL)3279 GLINTCloseScreen(CLOSE_SCREEN_ARGS_DECL)
3280 {
3281     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
3282     GLINTPtr pGlint = GLINTPTR(pScrn);
3283 
3284     TRACE_ENTER("GLINTCloseScreen");
3285 
3286     switch (pGlint->Chipset) {
3287         case PCI_VENDOR_TI_CHIP_PERMEDIA2:
3288         case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
3289         case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
3290 	    Permedia2VideoUninit(pScrn);
3291 	    break;
3292     }
3293 
3294     if (pScrn->vtSema) {
3295 	if(pGlint->CursorInfoRec)
3296     	    pGlint->CursorInfoRec->HideCursor(pScrn);
3297 	if (pGlint->FBDev)
3298 	    fbdevHWRestore(pScrn);
3299 	else {
3300 	    pGlint->STATE = TRUE;
3301             GLINTRestore(pScrn);
3302 	}
3303         GLINTUnmapMem(pScrn);
3304     }
3305 #ifdef HAVE_XAA_H
3306     if(pGlint->AccelInfoRec)
3307 	XAADestroyInfoRec(pGlint->AccelInfoRec);
3308 #endif
3309     if(pGlint->CursorInfoRec)
3310 	xf86DestroyCursorInfoRec(pGlint->CursorInfoRec);
3311     free(pGlint->ShadowPtr);
3312     free(pGlint->DGAModes);
3313     free(pGlint->ScratchBuffer);
3314     pScrn->vtSema = FALSE;
3315 
3316 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
3317     if (xf86IsPc98())
3318        outb(0xfac, 0x00);
3319 #endif
3320 
3321     if(pGlint->BlockHandler)
3322 	pScreen->BlockHandler = pGlint->BlockHandler;
3323 
3324     pScreen->CloseScreen = pGlint->CloseScreen;
3325     TRACE_EXIT("GLINTCloseScreen");
3326     return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
3327 }
3328 
3329 
3330 /* Free up any per-generation data structures */
3331 
3332 /* Optional */
3333 static void
GLINTFreeScreen(FREE_SCREEN_ARGS_DECL)3334 GLINTFreeScreen(FREE_SCREEN_ARGS_DECL)
3335 {
3336     SCRN_INFO_PTR(arg);
3337     TRACE_ENTER("GLINTFreeScreen");
3338     if (xf86LoaderCheckSymbol("fbdevHWFreeRec"))
3339         fbdevHWFreeRec(pScrn);
3340     if (xf86LoaderCheckSymbol("RamDacFreeRec"))
3341 	RamDacFreeRec(pScrn);
3342     GLINTFreeRec(pScrn);
3343     TRACE_EXIT("GLINTFreeScreen");
3344 }
3345 
3346 
3347 /* Checks if a mode is suitable for the selected chipset. */
3348 
3349 /* Optional */
3350 static ModeStatus
GLINTValidMode(SCRN_ARG_TYPE arg,DisplayModePtr mode,Bool verbose,int flags)3351 GLINTValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
3352 {
3353     SCRN_INFO_PTR(arg);
3354     GLINTPtr pGlint = GLINTPTR(pScrn);
3355 
3356     if (mode->Flags & V_INTERLACE)
3357 	return(MODE_NO_INTERLACE);
3358 
3359     if (pScrn->bitsPerPixel == 24) {
3360 	/* A restriction on the PM2 where a black strip on the left hand
3361 	 * side appears if not aligned properly */
3362         switch (pGlint->Chipset) {
3363         case PCI_VENDOR_TI_CHIP_PERMEDIA2:
3364         case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
3365 	case PCI_VENDOR_3DLABS_CHIP_R4:
3366         case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
3367         case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
3368         case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
3369           if (mode->HDisplay % 8) {
3370 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3371 	      "HDisplay %d not divisible by 8, fixing...\n", mode->HDisplay);
3372 	    mode->HDisplay -= (mode->HDisplay % 8);
3373 	    mode->CrtcHDisplay = mode->CrtcHBlankStart = mode->HDisplay;
3374           }
3375 
3376           if (mode->HSyncStart % 8) {
3377 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3378 	     "HSyncStart %d not divisible by 8, fixing...\n", mode->HSyncStart);
3379 	    mode->HSyncStart -= (mode->HSyncStart % 8);
3380 	    mode->CrtcHSyncStart = mode->HSyncStart;
3381           }
3382 
3383           if (mode->HSyncEnd % 8) {
3384 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3385 	      "HSyncEnd %d not divisible by 8, fixing...\n", mode->HSyncEnd);
3386 	    mode->HSyncEnd -= (mode->HSyncEnd % 8);
3387 	    mode->CrtcHSyncEnd = mode->HSyncEnd;
3388           }
3389 
3390           if (mode->HTotal % 8) {
3391 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3392 	      "HTotal %d not divisible by 8, fixing...\n", mode->HTotal);
3393 	    mode->HTotal -= (mode->HTotal % 8);
3394 	    mode->CrtcHBlankEnd = mode->CrtcHTotal = mode->HTotal;
3395           }
3396           break;
3397 	}
3398     }
3399 
3400     return(MODE_OK);
3401 }
3402 
3403 /* Do screen blanking */
3404 
3405 /* Mandatory */
3406 static Bool
GLINTSaveScreen(ScreenPtr pScreen,int mode)3407 GLINTSaveScreen(ScreenPtr pScreen, int mode)
3408 {
3409     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
3410     GLINTPtr pGlint = GLINTPTR(pScrn);
3411     CARD32 temp;
3412     Bool unblank;
3413 
3414     TRACE_ENTER("GLINTSaveScreen");
3415 
3416     unblank = xf86IsUnblank(mode);
3417 
3418     if (unblank)
3419 	SetTimeSinceLastInputEvent();
3420 
3421     if ((pScrn != NULL ) && pScrn->vtSema) {
3422 	switch (pGlint->Chipset) {
3423 	case PCI_VENDOR_TI_CHIP_PERMEDIA2:
3424 	case PCI_VENDOR_TI_CHIP_PERMEDIA:
3425 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
3426 	case PCI_VENDOR_3DLABS_CHIP_R4:
3427 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
3428 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
3429 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
3430 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
3431 	    temp = GLINT_READ_REG(PMVideoControl);
3432 	    if (unblank) temp |= 1;
3433 	    else	     temp &= 0xFFFFFFFE;
3434 	    GLINT_SLOW_WRITE_REG(temp, PMVideoControl);
3435 	    break;
3436 	case PCI_VENDOR_3DLABS_CHIP_500TX:
3437 	case PCI_VENDOR_3DLABS_CHIP_300SX:
3438 	case PCI_VENDOR_3DLABS_CHIP_MX:
3439 	    break;
3440 	case PCI_VENDOR_3DLABS_CHIP_GAMMA:
3441 	case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
3442 	case PCI_VENDOR_3DLABS_CHIP_DELTA:
3443 	    switch (pGlint->MultiChip) {
3444 		case PCI_CHIP_3DLABS_R4:
3445 	    	case PCI_CHIP_3DLABS_PERMEDIA3:
3446 	    	case PCI_CHIP_3DLABS_PERMEDIA:
3447 	    	case PCI_CHIP_TI_PERMEDIA:
3448 	    	    temp = GLINT_READ_REG(PMVideoControl);
3449 	    	    if (unblank) temp |= 1;
3450 	    	    else	     temp &= 0xFFFFFFFE;
3451 	    	    GLINT_SLOW_WRITE_REG(temp, PMVideoControl);
3452 	        break;
3453 	    }
3454 	    break;
3455 	}
3456     }
3457 
3458     TRACE_EXIT("GLINTSaveScreen");
3459     return TRUE;
3460 }
3461 
3462 static void
GLINTBlockHandler(BLOCKHANDLER_ARGS_DECL)3463 GLINTBlockHandler (BLOCKHANDLER_ARGS_DECL)
3464 {
3465     SCREEN_PTR(arg);
3466     ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
3467     GLINTPtr       pGlint = GLINTPTR(pScrn);
3468     int sigstate = xf86BlockSIGIO();
3469 
3470     if(pGlint->CursorColorCallback)
3471 	(*pGlint->CursorColorCallback)(pScrn);
3472 
3473     if(pGlint->LoadCursorCallback)
3474 	(*pGlint->LoadCursorCallback)(pScrn);
3475 
3476     xf86UnblockSIGIO(sigstate);
3477 
3478     pScreen->BlockHandler = pGlint->BlockHandler;
3479     (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
3480     pScreen->BlockHandler = GLINTBlockHandler;
3481 
3482     if(pGlint->VideoTimerCallback) {
3483 	UpdateCurrentTime();
3484 	(*pGlint->VideoTimerCallback)(pScrn, currentTime.milliseconds);
3485     }
3486 }
3487 
3488 #ifdef DEBUG
3489 void
GLINT_VERB_WRITE_REG(GLINTPtr pGlint,CARD32 v,int r,char * file,int line)3490 GLINT_VERB_WRITE_REG(GLINTPtr pGlint, CARD32 v, int r, char *file, int line)
3491 {
3492     if (xf86GetVerbosity() > 2)
3493 	ErrorF("[0x%04x] <- 0x%08lx (%s, %d)\n",
3494 		r, (unsigned long)v, file, line);
3495     *(volatile CARD32 *)((char *) pGlint->IOBase + pGlint->IOOffset + r) = v;
3496 }
3497 
3498 CARD32
GLINT_VERB_READ_REG(GLINTPtr pGlint,CARD32 r,char * file,int line)3499 GLINT_VERB_READ_REG(GLINTPtr pGlint, CARD32 r, char *file, int line)
3500 {
3501     CARD32 v =
3502 	*(volatile CARD32 *)((char *) pGlint->IOBase + pGlint->IOOffset + r);
3503 
3504     if (xf86GetVerbosity() > 2)
3505 	ErrorF("[0x%04lx] -> 0x%08lx (%s, %d)\n", (unsigned long)r,
3506 		(unsigned long)v, file, line);
3507     return v;
3508 }
3509 #endif
3510 
GLINT_MoveBYTE(register CARD32 * dest,register unsigned char * src,register int dwords)3511 void GLINT_MoveBYTE(
3512    register CARD32* dest,
3513    register unsigned char* src,
3514    register int dwords)
3515 {
3516 #ifdef __alpha__
3517      write_mem_barrier();
3518 #endif
3519      while(dwords) {
3520 	*dest = *src;
3521 	src += 1;
3522 	dest += 1;
3523 	dwords -= 1;
3524      }
3525 }
3526 
GLINT_MoveWORDS(register CARD32 * dest,register unsigned short * src,register int dwords)3527 void GLINT_MoveWORDS(
3528    register CARD32* dest,
3529    register unsigned short* src,
3530    register int dwords)
3531 {
3532 #ifdef __alpha__
3533      write_mem_barrier();
3534 #endif
3535      while(dwords & ~0x01) {
3536 	*dest = *src;
3537 	*(dest + 1) = *(src + 1);
3538 	src += 2;
3539 	dest += 2;
3540 	dwords -= 2;
3541      }
3542      if (dwords)
3543         *dest = *src;
3544 }
3545 
GLINT_MoveDWORDS(register CARD32 * dest,register CARD32 * src,register int dwords)3546 void GLINT_MoveDWORDS(
3547    register CARD32* dest,
3548    register CARD32* src,
3549    register int dwords)
3550 {
3551 #ifdef __alpha__
3552      write_mem_barrier();
3553 #endif
3554     if ((unsigned long)src & 0x3UL) {
3555 	    unsigned char *pchar;
3556 	    while (dwords & ~0x03) {
3557 		    pchar = (unsigned char *)(src + 0);
3558 		    *(dest + 0) = (((CARD32)pchar[0] << 24) |
3559 				   ((CARD32)pchar[1] << 16) |
3560 				   ((CARD32)pchar[2] << 8) |
3561 				   ((CARD32)pchar[3] << 0));
3562 		    pchar = (unsigned char *)(src + 1);
3563 		    *(dest + 1) = (((CARD32)pchar[0] << 24) |
3564 				   ((CARD32)pchar[1] << 16) |
3565 				   ((CARD32)pchar[2] << 8) |
3566 				   ((CARD32)pchar[3] << 0));
3567 		    pchar = (unsigned char *)(src + 2);
3568 		    *(dest + 2) = (((CARD32)pchar[0] << 24) |
3569 				   ((CARD32)pchar[1] << 16) |
3570 				   ((CARD32)pchar[2] << 8) |
3571 				   ((CARD32)pchar[3] << 0));
3572 		    pchar = (unsigned char *)(src + 3);
3573 		    *(dest + 3) = (((CARD32)pchar[0] << 24) |
3574 				   ((CARD32)pchar[1] << 16) |
3575 				   ((CARD32)pchar[2] << 8) |
3576 				   ((CARD32)pchar[3] << 0));
3577 		    src += 4;
3578 		    dest += 4;
3579 		    dwords -= 4;
3580 	    }
3581 	    if (!dwords)
3582 		    return;
3583 	    pchar = (unsigned char *)(src + 0);
3584 	    *(dest + 0) = (((CARD32)pchar[0] << 24) |
3585 			   ((CARD32)pchar[1] << 16) |
3586 			   ((CARD32)pchar[2] << 8) |
3587 			   ((CARD32)pchar[3] << 0));
3588 	    if (dwords == 1)
3589 		    return;
3590 	    pchar = (unsigned char *)(src + 1);
3591 	    *(dest + 1) = (((CARD32)pchar[0] << 24) |
3592 			   ((CARD32)pchar[1] << 16) |
3593 			   ((CARD32)pchar[2] << 8) |
3594 			   ((CARD32)pchar[3] << 0));
3595 	    if (dwords == 2)
3596 		    return;
3597 	    pchar = (unsigned char *)(src + 2);
3598 	    *(dest + 2) = (((CARD32)pchar[0] << 24) |
3599 			   ((CARD32)pchar[1] << 16) |
3600 			   ((CARD32)pchar[2] << 8) |
3601 			   ((CARD32)pchar[3] << 0));
3602     } else {
3603 	    while (dwords & ~0x03) {
3604 		    *dest = *src;
3605 		    *(dest + 1) = *(src + 1);
3606 		    *(dest + 2) = *(src + 2);
3607 		    *(dest + 3) = *(src + 3);
3608 		    src += 4;
3609 		    dest += 4;
3610 		    dwords -= 4;
3611 	    }
3612 	    if (!dwords)
3613 		    return;
3614 	    *dest = *src;
3615 	    if (dwords == 1)
3616 		    return;
3617 	    *(dest + 1) = *(src + 1);
3618 	    if (dwords == 2)
3619 		    return;
3620 	    *(dest + 2) = *(src + 2);
3621     }
3622 }
3623 
3624 int
Shiftbpp(ScrnInfoPtr pScrn,int value)3625 Shiftbpp(ScrnInfoPtr pScrn, int value)
3626 {
3627     GLINTPtr pGlint = GLINTPTR(pScrn);
3628     int logbytesperaccess = 2; /* default */
3629 
3630     switch (pGlint->Chipset) {
3631 	case PCI_VENDOR_TI_CHIP_PERMEDIA:
3632 	case PCI_VENDOR_TI_CHIP_PERMEDIA2:
3633 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
3634 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
3635 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
3636 	    logbytesperaccess = 2;
3637 	    break;
3638 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
3639 	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
3640 	case PCI_VENDOR_3DLABS_CHIP_R4:
3641 	    logbytesperaccess = 4;
3642 	    break;
3643 	case PCI_VENDOR_3DLABS_CHIP_300SX:
3644 	case PCI_VENDOR_3DLABS_CHIP_500TX:
3645 	case PCI_VENDOR_3DLABS_CHIP_MX:
3646     	    if ( (pGlint->RamDac->RamDacType == (IBM640_RAMDAC)) ||
3647                  (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) )
3648     		logbytesperaccess = 4;
3649     	    else
3650     	 	logbytesperaccess = 3;
3651 	    break;
3652 	case PCI_VENDOR_3DLABS_CHIP_GAMMA:
3653 	case PCI_VENDOR_3DLABS_CHIP_GAMMA2:
3654 	case PCI_VENDOR_3DLABS_CHIP_DELTA:
3655 	    switch (pGlint->MultiChip) {
3656 		case PCI_CHIP_3DLABS_500TX:
3657 		case PCI_CHIP_3DLABS_300SX:
3658 		case PCI_CHIP_3DLABS_MX:
3659     	    	if ( (pGlint->RamDac->RamDacType == (IBM640_RAMDAC)) ||
3660                      (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) )
3661     		    logbytesperaccess = 4;
3662     	    	else
3663     	 	    logbytesperaccess = 3;
3664 		break;
3665 		case PCI_CHIP_3DLABS_PERMEDIA:
3666 		case PCI_CHIP_TI_PERMEDIA:
3667 	    	    logbytesperaccess = 2;
3668 	            break;
3669 		case PCI_CHIP_3DLABS_R4:
3670 		case PCI_CHIP_3DLABS_PERMEDIA3:
3671 	    	    logbytesperaccess = 4;
3672 	            break;
3673 	    }
3674     }
3675 
3676     switch (pScrn->bitsPerPixel) {
3677     case 8:
3678 	value >>= logbytesperaccess;
3679 	pGlint->BppShift = logbytesperaccess;
3680 	break;
3681     case 16:
3682 	if (pGlint->DoubleBuffer) {
3683 	    value >>= (logbytesperaccess-2);
3684 	    pGlint->BppShift = logbytesperaccess-2;
3685 	} else {
3686 	    value >>= (logbytesperaccess-1);
3687 	    pGlint->BppShift = logbytesperaccess-1;
3688 	}
3689 	break;
3690     case 24:
3691 	value *= 3;
3692 	value >>= logbytesperaccess;
3693 	pGlint->BppShift = logbytesperaccess;
3694 	break;
3695     case 32:
3696 	value >>= (logbytesperaccess-2);
3697 	pGlint->BppShift = logbytesperaccess-2;
3698 	break;
3699     }
3700     return (value);
3701 }
3702