merge in the nv50 code from the randr 1.2 branch
[nouveau] / src / nv_driver.c
1 /* $XdotOrg: driver/xf86-video-nv/src/nv_driver.c,v 1.21 2006/01/24 16:45:29 aplattner Exp $ */
2 /* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
3 /*
4  * Copyright 1996-1997  David J. McKay
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
21  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24
25 /* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen
26    <jpaana@s2.org> */
27
28 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.144 2006/06/16 00:19:32 mvojkovi Exp $ */
29
30 #include "nv_include.h"
31
32 #include "xf86int10.h"
33
34 #include "xf86drm.h"
35
36 extern DisplayModePtr xf86ModesAdd(DisplayModePtr Modes, DisplayModePtr Additions);
37
38 /*const   OptionInfoRec * RivaAvailableOptions(int chipid, int busid);
39 Bool    RivaGetScrnInfoRec(PciChipsets *chips, int chip);*/
40
41 /*
42  * Forward definitions for the functions that make up the driver.
43  */
44 /* Mandatory functions */
45 static const OptionInfoRec * NVAvailableOptions(int chipid, int busid);
46 static void    NVIdentify(int flags);
47 static Bool    NVProbe(DriverPtr drv, int flags);
48 static Bool    NVPreInit(ScrnInfoPtr pScrn, int flags);
49 static Bool    NVScreenInit(int Index, ScreenPtr pScreen, int argc,
50                             char **argv);
51 static Bool    NVEnterVT(int scrnIndex, int flags);
52 static void    NVLeaveVT(int scrnIndex, int flags);
53 static Bool    NVCloseScreen(int scrnIndex, ScreenPtr pScreen);
54 static Bool    NVSaveScreen(ScreenPtr pScreen, int mode);
55
56 /* Optional functions */
57 static void    NVFreeScreen(int scrnIndex, int flags);
58 static ModeStatus NVValidMode(int scrnIndex, DisplayModePtr mode,
59                               Bool verbose, int flags);
60 #ifdef RANDR
61 static Bool    NVDriverFunc(ScrnInfoPtr pScrnInfo, xorgDriverFuncOp op,
62                               pointer data);
63 #endif
64
65 /* Internally used functions */
66
67 static Bool     NVMapMem(ScrnInfoPtr pScrn);
68 static Bool     NVUnmapMem(ScrnInfoPtr pScrn);
69 static void     NVSave(ScrnInfoPtr pScrn);
70 static void     NVRestore(ScrnInfoPtr pScrn);
71 static Bool     NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
72
73
74 /*
75  * This contains the functions needed by the server after loading the
76  * driver module.  It must be supplied, and gets added the driver list by
77  * the Module Setup funtion in the dynamic case.  In the static case a
78  * reference to this is compiled in, and this requires that the name of
79  * this DriverRec be an upper-case version of the driver name.
80  */
81
82 _X_EXPORT DriverRec NV = {
83         NV_VERSION,
84         NV_DRIVER_NAME,
85         NVIdentify,
86         NVProbe,
87         NVAvailableOptions,
88         NULL,
89         0
90 };
91
92 struct NvFamily
93 {
94   char *name;
95   char *chipset;
96 };
97
98 static struct NvFamily NVKnownFamilies[] =
99 {
100   { "RIVA TNT",    "NV04" },
101   { "RIVA TNT2",   "NV05" },
102   { "GeForce 256", "NV10" },
103   { "GeForce 2",   "NV11, NV15" },
104   { "GeForce 4MX", "NV17, NV18" },
105   { "GeForce 3",   "NV20" },
106   { "GeForce 4Ti", "NV25, NV28" },
107   { "GeForce FX",  "NV3x" },
108   { "GeForce 6",   "NV4x" },
109   { "GeForce 7",   "G7x" },
110   { NULL, NULL}
111 };
112
113 /* Known cards as of 2006/06/16 */
114
115 static SymTabRec NVKnownChipsets[] =
116 {
117   { 0x12D20018, "RIVA 128" },
118   { 0x12D20019, "RIVA 128ZX" },
119
120   { 0x10DE0020, "RIVA TNT" },
121
122   { 0x10DE0028, "RIVA TNT2" },
123   { 0x10DE002A, "Unknown TNT2" },
124   { 0x10DE002C, "Vanta" },
125   { 0x10DE0029, "RIVA TNT2 Ultra" },
126   { 0x10DE002D, "RIVA TNT2 Model 64" },
127
128   { 0x10DE00A0, "Aladdin TNT2" },
129
130   { 0x10DE0100, "GeForce 256" },
131   { 0x10DE0101, "GeForce DDR" },
132   { 0x10DE0103, "Quadro" },
133
134   { 0x10DE0110, "GeForce2 MX/MX 400" },
135   { 0x10DE0111, "GeForce2 MX 100/200" },
136   { 0x10DE0112, "GeForce2 Go" },
137   { 0x10DE0113, "Quadro2 MXR/EX/Go" },
138
139   { 0x10DE01A0, "GeForce2 Integrated GPU" },
140
141   { 0x10DE0150, "GeForce2 GTS" },
142   { 0x10DE0151, "GeForce2 Ti" },
143   { 0x10DE0152, "GeForce2 Ultra" },
144   { 0x10DE0153, "Quadro2 Pro" },
145
146   { 0x10DE0170, "GeForce4 MX 460" },
147   { 0x10DE0171, "GeForce4 MX 440" },
148   { 0x10DE0172, "GeForce4 MX 420" },
149   { 0x10DE0173, "GeForce4 MX 440-SE" },
150   { 0x10DE0174, "GeForce4 440 Go" },
151   { 0x10DE0175, "GeForce4 420 Go" },
152   { 0x10DE0176, "GeForce4 420 Go 32M" },
153   { 0x10DE0177, "GeForce4 460 Go" },
154   { 0x10DE0178, "Quadro4 550 XGL" },
155 #if defined(__powerpc__)
156   { 0x10DE0179, "GeForce4 MX (Mac)" },
157 #else
158   { 0x10DE0179, "GeForce4 440 Go 64M" },
159 #endif
160   { 0x10DE017A, "Quadro NVS" },
161   { 0x10DE017C, "Quadro4 500 GoGL" },
162   { 0x10DE017D, "GeForce4 410 Go 16M" },
163
164   { 0x10DE0181, "GeForce4 MX 440 with AGP8X" },
165   { 0x10DE0182, "GeForce4 MX 440SE with AGP8X" },
166   { 0x10DE0183, "GeForce4 MX 420 with AGP8X" },
167   { 0x10DE0185, "GeForce4 MX 4000" },
168   { 0x10DE0186, "GeForce4 448 Go" },
169   { 0x10DE0187, "GeForce4 488 Go" },
170   { 0x10DE0188, "Quadro4 580 XGL" },
171 #if defined(__powerpc__)
172   { 0x10DE0189, "GeForce4 MX with AGP8X (Mac)" },
173 #endif
174   { 0x10DE018A, "Quadro4 NVS 280 SD" },
175   { 0x10DE018B, "Quadro4 380 XGL" },
176   { 0x10DE018C, "Quadro NVS 50 PCI" },
177   { 0x10DE018D, "GeForce4 448 Go" },
178
179   { 0x10DE01F0, "GeForce4 MX Integrated GPU" },
180
181   { 0x10DE0200, "GeForce3" },
182   { 0x10DE0201, "GeForce3 Ti 200" },
183   { 0x10DE0202, "GeForce3 Ti 500" },
184   { 0x10DE0203, "Quadro DCC" },
185
186   { 0x10DE0250, "GeForce4 Ti 4600" },
187   { 0x10DE0251, "GeForce4 Ti 4400" },
188   { 0x10DE0253, "GeForce4 Ti 4200" },
189   { 0x10DE0258, "Quadro4 900 XGL" },
190   { 0x10DE0259, "Quadro4 750 XGL" },
191   { 0x10DE025B, "Quadro4 700 XGL" },
192
193   { 0x10DE0280, "GeForce4 Ti 4800" },
194   { 0x10DE0281, "GeForce4 Ti 4200 with AGP8X" },
195   { 0x10DE0282, "GeForce4 Ti 4800 SE" },
196   { 0x10DE0286, "GeForce4 4200 Go" },
197   { 0x10DE028C, "Quadro4 700 GoGL" },
198   { 0x10DE0288, "Quadro4 980 XGL" },
199   { 0x10DE0289, "Quadro4 780 XGL" },
200
201   { 0x10DE0301, "GeForce FX 5800 Ultra" },
202   { 0x10DE0302, "GeForce FX 5800" },
203   { 0x10DE0308, "Quadro FX 2000" },
204   { 0x10DE0309, "Quadro FX 1000" },
205
206   { 0x10DE0311, "GeForce FX 5600 Ultra" },
207   { 0x10DE0312, "GeForce FX 5600" },
208   { 0x10DE0314, "GeForce FX 5600XT" },
209   { 0x10DE031A, "GeForce FX Go5600" },
210   { 0x10DE031B, "GeForce FX Go5650" },
211   { 0x10DE031C, "Quadro FX Go700" },
212
213   { 0x10DE0320, "GeForce FX 5200" },
214   { 0x10DE0321, "GeForce FX 5200 Ultra" },
215   { 0x10DE0322, "GeForce FX 5200" },
216   { 0x10DE0323, "GeForce FX 5200LE" },
217   { 0x10DE0324, "GeForce FX Go5200" },
218   { 0x10DE0325, "GeForce FX Go5250" },
219   { 0x10DE0326, "GeForce FX 5500" },
220   { 0x10DE0327, "GeForce FX 5100" },
221   { 0x10DE0328, "GeForce FX Go5200 32M/64M" },
222 #if defined(__powerpc__)
223   { 0x10DE0329, "GeForce FX 5200 (Mac)" },
224 #endif
225   { 0x10DE032A, "Quadro NVS 55/280 PCI" },
226   { 0x10DE032B, "Quadro FX 500/600 PCI" },
227   { 0x10DE032C, "GeForce FX Go53xx Series" },
228   { 0x10DE032D, "GeForce FX Go5100" },
229
230   { 0x10DE0330, "GeForce FX 5900 Ultra" },
231   { 0x10DE0331, "GeForce FX 5900" },
232   { 0x10DE0332, "GeForce FX 5900XT" },
233   { 0x10DE0333, "GeForce FX 5950 Ultra" },
234   { 0x10DE0334, "GeForce FX 5900ZT" },
235   { 0x10DE0338, "Quadro FX 3000" },
236   { 0x10DE033F, "Quadro FX 700" },
237
238   { 0x10DE0341, "GeForce FX 5700 Ultra" },
239   { 0x10DE0342, "GeForce FX 5700" },
240   { 0x10DE0343, "GeForce FX 5700LE" },
241   { 0x10DE0344, "GeForce FX 5700VE" },
242   { 0x10DE0347, "GeForce FX Go5700" },
243   { 0x10DE0348, "GeForce FX Go5700" },
244   { 0x10DE034C, "Quadro FX Go1000" },
245   { 0x10DE034E, "Quadro FX 1100" },
246
247   { 0x10DE0040, "GeForce 6800 Ultra" },
248   { 0x10DE0041, "GeForce 6800" },
249   { 0x10DE0042, "GeForce 6800 LE" },
250   { 0x10DE0043, "GeForce 6800 XE" },
251   { 0x10DE0044, "GeForce 6800 XT" },
252   { 0x10DE0045, "GeForce 6800 GT" },
253   { 0x10DE0046, "GeForce 6800 GT" },
254   { 0x10DE0047, "GeForce 6800 GS" },
255   { 0x10DE0048, "GeForce 6800 XT" },
256   { 0x10DE004E, "Quadro FX 4000" },
257
258   { 0x10DE00C0, "GeForce 6800 GS" },
259   { 0x10DE00C1, "GeForce 6800" },
260   { 0x10DE00C2, "GeForce 6800 LE" },
261   { 0x10DE00C3, "GeForce 6800 XT" },
262   { 0x10DE00C8, "GeForce Go 6800" },
263   { 0x10DE00C9, "GeForce Go 6800 Ultra" },
264   { 0x10DE00CC, "Quadro FX Go1400" },
265   { 0x10DE00CD, "Quadro FX 3450/4000 SDI" },
266   { 0x10DE00CE, "Quadro FX 1400" },
267
268   { 0x10DE0140, "GeForce 6600 GT" },
269   { 0x10DE0141, "GeForce 6600" },
270   { 0x10DE0142, "GeForce 6600 LE" },
271   { 0x10DE0143, "GeForce 6600 VE" },
272   { 0x10DE0144, "GeForce Go 6600" },
273   { 0x10DE0145, "GeForce 6610 XL" },
274   { 0x10DE0146, "GeForce Go 6600 TE/6200 TE" },
275   { 0x10DE0147, "GeForce 6700 XL" },
276   { 0x10DE0148, "GeForce Go 6600" },
277   { 0x10DE0149, "GeForce Go 6600 GT" },
278   { 0x10DE014C, "Quadro FX 550" },
279   { 0x10DE014D, "Quadro FX 550" },
280   { 0x10DE014E, "Quadro FX 540" },
281   { 0x10DE014F, "GeForce 6200" },
282
283   { 0x10DE0160, "GeForce 6500" },
284   { 0x10DE0161, "GeForce 6200 TurboCache(TM)" },
285   { 0x10DE0162, "GeForce 6200SE TurboCache(TM)" },
286   { 0x10DE0163, "GeForce 6200 LE" },
287   { 0x10DE0164, "GeForce Go 6200" },
288   { 0x10DE0165, "Quadro NVS 285" },
289   { 0x10DE0166, "GeForce Go 6400" },
290   { 0x10DE0167, "GeForce Go 6200" },
291   { 0x10DE0168, "GeForce Go 6400" },
292   { 0x10DE0169, "GeForce 6250" },
293
294   { 0x10DE0211, "GeForce 6800" },
295   { 0x10DE0212, "GeForce 6800 LE" },
296   { 0x10DE0215, "GeForce 6800 GT" },
297   { 0x10DE0218, "GeForce 6800 XT" },
298
299   { 0x10DE0221, "GeForce 6200" },
300   { 0x10DE0222, "GeForce 6200 A-LE" },
301
302   { 0x10DE0090, "GeForce 7800 GTX" },
303   { 0x10DE0091, "GeForce 7800 GTX" },
304   { 0x10DE0092, "GeForce 7800 GT" },
305   { 0x10DE0093, "GeForce 7800 GS" },
306   { 0x10DE0095, "GeForce 7800 SLI" },
307   { 0x10DE0098, "GeForce Go 7800" },
308   { 0x10DE0099, "GeForce Go 7800 GTX" },
309   { 0x10DE009D, "Quadro FX 4500" },
310
311   { 0x10DE01D1, "GeForce 7300 LE" },
312   { 0x10DE01D3, "GeForce 7300 SE" },
313   { 0x10DE01D6, "GeForce Go 7200" },
314   { 0x10DE01D7, "GeForce Go 7300" },
315   { 0x10DE01D8, "GeForce Go 7400" },
316   { 0x10DE01D9, "GeForce Go 7400 GS" },
317   { 0x10DE01DA, "Quadro NVS 110M" },
318   { 0x10DE01DB, "Quadro NVS 120M" },
319   { 0x10DE01DC, "Quadro FX 350M" },
320   { 0x10DE01DD, "GeForce 7500 LE" },
321   { 0x10DE01DE, "Quadro FX 350" },
322   { 0x10DE01DF, "GeForce 7300 GS" },
323
324   { 0x10DE0391, "GeForce 7600 GT" },
325   { 0x10DE0392, "GeForce 7600 GS" },
326   { 0x10DE0393, "GeForce 7300 GT" },
327   { 0x10DE0394, "GeForce 7600 LE" },
328   { 0x10DE0395, "GeForce 7300 GT" },
329   { 0x10DE0397, "GeForce Go 7700" },
330   { 0x10DE0398, "GeForce Go 7600" },
331   { 0x10DE0399, "GeForce Go 7600 GT"},
332   { 0x10DE039A, "Quadro NVS 300M" },
333   { 0x10DE039B, "GeForce Go 7900 SE" },
334   { 0x10DE039C, "Quadro FX 550M" },
335   { 0x10DE039E, "Quadro FX 560" },
336
337   { 0x10DE0290, "GeForce 7900 GTX" },
338   { 0x10DE0291, "GeForce 7900 GT" },
339   { 0x10DE0292, "GeForce 7900 GS" },
340   { 0x10DE0298, "GeForce Go 7900 GS" },
341   { 0x10DE0299, "GeForce Go 7900 GTX" },
342   { 0x10DE029A, "Quadro FX 2500M" },
343   { 0x10DE029B, "Quadro FX 1500M" },
344   { 0x10DE029C, "Quadro FX 5500" },
345   { 0x10DE029D, "Quadro FX 3500" },
346   { 0x10DE029E, "Quadro FX 1500" },
347   { 0x10DE029F, "Quadro FX 4500 X2" },
348
349   { 0x10DE0240, "GeForce 6150" },
350   { 0x10DE0241, "GeForce 6150 LE" },
351   { 0x10DE0242, "GeForce 6100" },
352   { 0x10DE0244, "GeForce Go 6150" },
353   { 0x10DE0247, "GeForce Go 6100" },
354
355   {-1, NULL}
356 };
357
358
359 /*
360  * List of symbols from other modules that this module references.  This
361  * list is used to tell the loader that it is OK for symbols here to be
362  * unresolved providing that it hasn't been told that they haven't been
363  * told that they are essential via a call to xf86LoaderReqSymbols() or
364  * xf86LoaderReqSymLists().  The purpose is this is to avoid warnings about
365  * unresolved symbols that are not required.
366  */
367
368 static const char *vgahwSymbols[] = {
369     "vgaHWUnmapMem",
370     "vgaHWDPMSSet",
371     "vgaHWFreeHWRec",
372     "vgaHWGetHWRec",
373     "vgaHWGetIndex",
374     "vgaHWInit",
375     "vgaHWMapMem",
376     "vgaHWProtect",
377     "vgaHWRestore",
378     "vgaHWSave",
379     "vgaHWSaveScreen",
380     NULL
381 };
382
383 static const char *fbSymbols[] = {
384     "fbPictureInit",
385     "fbScreenInit",
386     NULL
387 };
388
389 static const char *xaaSymbols[] = {
390     "XAACopyROP",
391     "XAACreateInfoRec",
392     "XAADestroyInfoRec",
393     "XAAFallbackOps",
394     "XAAInit",
395     "XAAPatternROP",
396     NULL
397 };
398
399 static const char *exaSymbols[] = {
400     "exaDriverInit",
401     "exaOffscreenInit",
402     NULL
403 };
404
405 static const char *ramdacSymbols[] = {
406     "xf86CreateCursorInfoRec",
407     "xf86DestroyCursorInfoRec",
408     "xf86InitCursor",
409     NULL
410 };
411
412 static const char *ddcSymbols[] = {
413     "xf86PrintEDID",
414     "xf86DoEDID_DDC2",
415     "xf86SetDDCproperties",
416     NULL
417 };
418
419 static const char *vbeSymbols[] = {
420     "VBEInit",
421     "vbeFree",
422     "vbeDoEDID",
423     NULL
424 };
425
426 static const char *i2cSymbols[] = {
427     "xf86CreateI2CBusRec",
428     "xf86I2CBusInit",
429     NULL
430 };
431
432 static const char *shadowSymbols[] = {
433     "ShadowFBInit",
434     NULL
435 };
436
437 static const char *int10Symbols[] = {
438     "xf86FreeInt10",
439     "xf86InitInt10",
440     NULL
441 };
442
443 static const char *rivaSymbols[] = {
444    "RivaGetScrnInfoRec",
445    "RivaAvailableOptions",
446     NULL
447 };
448
449 const char *drmSymbols[] = {
450     "drmOpen", 
451     "drmAddBufs",
452     "drmAddMap",
453     "drmAgpAcquire",
454     "drmAgpVersionMajor",
455     "drmAgpVersionMinor",
456     "drmAgpAlloc",
457     "drmAgpBind",
458     "drmAgpEnable",
459     "drmAgpFree",
460     "drmAgpRelease",
461     "drmAgpUnbind",
462     "drmAuthMagic",
463     "drmCommandNone",
464     "drmCommandWrite",
465     "drmCommandWriteRead",
466     "drmCreateContext",
467     "drmCtlInstHandler",
468     "drmCtlUninstHandler",
469     "drmDestroyContext",
470     "drmFreeVersion",
471     "drmGetInterruptFromBusID",
472     "drmGetLibVersion",
473     "drmGetVersion",
474     NULL
475 };
476
477 const char *driSymbols[] = {
478     "DRICloseScreen",
479     "DRICreateInfoRec",
480     "DRIDestroyInfoRec",
481     "DRIFinishScreenInit",
482     "DRIGetSAREAPrivate",
483     "DRILock",
484     "DRIQueryVersion",
485     "DRIScreenInit",
486     "DRIUnlock",
487     "GlxSetVisualConfigs",
488     "DRICreatePCIBusID",
489     NULL
490 };
491
492
493 static MODULESETUPPROTO(nouveauSetup);
494
495 static XF86ModuleVersionInfo nouveauVersRec =
496 {
497     "nouveau",
498     MODULEVENDORSTRING,
499     MODINFOSTRING1,
500     MODINFOSTRING2,
501     XORG_VERSION_CURRENT,
502     NV_MAJOR_VERSION, NV_MINOR_VERSION, NV_PATCHLEVEL,
503     ABI_CLASS_VIDEODRV,                     /* This is a video driver */
504     ABI_VIDEODRV_VERSION,
505     MOD_CLASS_VIDEODRV,
506     {0,0,0,0}
507 };
508
509 _X_EXPORT XF86ModuleData nouveauModuleData = { &nouveauVersRec, nouveauSetup, NULL };
510
511
512 /*
513  * This is intentionally screen-independent.  It indicates the binding
514  * choice made in the first PreInit.
515  */
516 static int pix24bpp = 0;
517
518 static Bool
519 NVGetRec(ScrnInfoPtr pScrn)
520 {
521     /*
522      * Allocate an NVRec, and hook it into pScrn->driverPrivate.
523      * pScrn->driverPrivate is initialised to NULL, so we can check if
524      * the allocation has already been done.
525      */
526     if (pScrn->driverPrivate != NULL)
527         return TRUE;
528
529     pScrn->driverPrivate = xnfcalloc(sizeof(NVRec), 1);
530     /* Initialise it */
531
532     return TRUE;
533 }
534
535 static void
536 NVFreeRec(ScrnInfoPtr pScrn)
537 {
538     if (pScrn->driverPrivate == NULL)
539         return;
540     xfree(pScrn->driverPrivate);
541     pScrn->driverPrivate = NULL;
542 }
543
544
545 static pointer
546 nouveauSetup(pointer module, pointer opts, int *errmaj, int *errmin)
547 {
548     static Bool setupDone = FALSE;
549
550     /* This module should be loaded only once, but check to be sure. */
551
552     if (!setupDone) {
553         setupDone = TRUE;
554         xf86AddDriver(&NV, module, 0);
555
556         /*
557          * Modules that this driver always requires may be loaded here
558          * by calling LoadSubModule().
559          */
560         /*
561          * Tell the loader about symbols from other modules that this module
562          * might refer to.
563          */
564         LoaderRefSymLists(vgahwSymbols, xaaSymbols, exaSymbols, fbSymbols,
565 #ifdef XF86DRI
566                           drmSymbols, 
567 #endif
568                           ramdacSymbols, shadowSymbols, rivaSymbols,
569                           i2cSymbols, ddcSymbols, vbeSymbols,
570                           int10Symbols, NULL);
571
572         /*
573          * The return value must be non-NULL on success even though there
574          * is no TearDownProc.
575          */
576         return (pointer)1;
577     } else {
578         if (errmaj) *errmaj = LDR_ONCEONLY;
579         return NULL;
580     }
581 }
582
583 static const OptionInfoRec *
584 NVAvailableOptions(int chipid, int busid)
585 {
586 /*    if(chipid == 0x12D20018) {
587         if (!xf86LoadOneModule("riva128", NULL)) {
588             return NULL;
589         } else
590             return RivaAvailableOptions(chipid, busid);
591     }*/
592     
593     return NVOptions;
594 }
595
596 /* Mandatory */
597 static void
598 NVIdentify(int flags)
599 {
600     struct NvFamily *family;
601     size_t maxLen=0;
602
603     xf86DrvMsg(0, X_INFO, NV_NAME " driver " NV_DRIVER_DATE "\n");
604     xf86DrvMsg(0, X_INFO, NV_NAME " driver for NVIDIA chipset families :\n");
605
606     /* maximum length for alignment */
607     family = NVKnownFamilies;
608     while(family->name && family->chipset)
609     {
610         maxLen = max(maxLen, strlen(family->name));
611         family++;
612     }
613
614     /* display */
615     family = NVKnownFamilies;
616     while(family->name && family->chipset)
617     {
618         size_t len = strlen(family->name);
619         xf86ErrorF("\t%s", family->name);
620         while(len<maxLen+1)
621         {
622             xf86ErrorF(" ");
623             len++;
624         }
625         xf86ErrorF("(%s)\n", family->chipset);
626         family++;
627     }
628 }
629
630
631 static Bool
632 NVGetScrnInfoRec(PciChipsets *chips, int chip)
633 {
634     ScrnInfoPtr pScrn;
635
636     pScrn = xf86ConfigPciEntity(NULL, 0, chip,
637                                 chips, NULL, NULL, NULL,
638                                 NULL, NULL);
639
640     if(!pScrn) return FALSE;
641
642     pScrn->driverVersion    = NV_VERSION;
643     pScrn->driverName       = NV_DRIVER_NAME;
644     pScrn->name             = NV_NAME;
645
646     pScrn->Probe            = NVProbe;
647     pScrn->PreInit          = NVPreInit;
648     pScrn->ScreenInit       = NVScreenInit;
649     pScrn->SwitchMode       = NVSwitchMode;
650     pScrn->AdjustFrame      = NVAdjustFrame;
651     pScrn->EnterVT          = NVEnterVT;
652     pScrn->LeaveVT          = NVLeaveVT;
653     pScrn->FreeScreen       = NVFreeScreen;
654     pScrn->ValidMode        = NVValidMode;
655
656     return TRUE;
657 }
658
659 #define MAX_CHIPS MAXSCREENS
660
661
662 static CARD32 
663 NVGetPCIXpressChip (pciVideoPtr pVideo)
664 {
665     volatile CARD32 *regs;
666     CARD32 pciid, pcicmd;
667     PCITAG Tag = ((pciConfigPtr)(pVideo->thisCard))->tag;
668
669     pcicmd = pciReadLong(Tag, PCI_CMD_STAT_REG);
670     pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd | PCI_CMD_MEM_ENABLE);
671     
672     regs = xf86MapPciMem(-1, VIDMEM_MMIO, Tag, pVideo->memBase[0], 0x2000);
673
674     pciid = regs[0x1800/4];
675
676     xf86UnMapVidMem(-1, (pointer)regs, 0x2000);
677
678     pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd);
679
680     if((pciid & 0x0000ffff) == 0x000010DE) 
681        pciid = 0x10DE0000 | (pciid >> 16);
682     else 
683     if((pciid & 0xffff0000) == 0xDE100000) /* wrong endian */
684        pciid = 0x10DE0000 | ((pciid << 8) & 0x0000ff00) |
685                             ((pciid >> 8) & 0x000000ff);
686
687     return pciid;
688 }
689
690
691 /* Mandatory */
692 static Bool
693 NVProbe(DriverPtr drv, int flags)
694 {
695     int i;
696     GDevPtr *devSections;
697     int *usedChips;
698     SymTabRec NVChipsets[MAX_CHIPS + 1];
699     PciChipsets NVPciChipsets[MAX_CHIPS + 1];
700     pciVideoPtr *ppPci;
701     int numDevSections;
702     int numUsed;
703     Bool foundScreen = FALSE;
704
705
706     if ((numDevSections = xf86MatchDevice(NV_DRIVER_NAME, &devSections)) <= 0) 
707         return FALSE;  /* no matching device section */
708
709     if (!(ppPci = xf86GetPciVideoInfo())) 
710         return FALSE;  /* no PCI cards found */
711
712     numUsed = 0;
713
714     /* Create the NVChipsets and NVPciChipsets from found devices */
715     while (*ppPci && (numUsed < MAX_CHIPS)) {
716         if(((*ppPci)->vendor == PCI_VENDOR_NVIDIA_SGS) || 
717            ((*ppPci)->vendor == PCI_VENDOR_NVIDIA)) 
718         {
719             SymTabRec *nvchips = NVKnownChipsets;
720             int pciid = ((*ppPci)->vendor << 16) | (*ppPci)->chipType;
721             int token = pciid;
722
723             if(((token & 0xfff0) == CHIPSET_MISC_BRIDGED) ||
724                ((token & 0xfff0) == CHIPSET_G73_BRIDGED))
725             {
726                 token = NVGetPCIXpressChip(*ppPci);
727             }
728
729             while(nvchips->name) {
730                if(token == nvchips->token)
731                   break;
732                nvchips++;
733             }
734
735             if(nvchips->name) { /* found one */
736                NVChipsets[numUsed].token = pciid;
737                NVChipsets[numUsed].name = nvchips->name;
738                NVPciChipsets[numUsed].numChipset = pciid; 
739                NVPciChipsets[numUsed].PCIid = pciid;
740                NVPciChipsets[numUsed].resList = RES_SHARED_VGA;
741                numUsed++;
742             } else if ((*ppPci)->vendor == PCI_VENDOR_NVIDIA) {
743                /* look for a compatible devices which may be newer than 
744                   the NVKnownChipsets list above.  */
745                switch(token & 0xfff0) {
746                case CHIPSET_NV17:
747                case CHIPSET_NV18:
748                case CHIPSET_NV25:
749                case CHIPSET_NV28:
750                case CHIPSET_NV30:
751                case CHIPSET_NV31:
752                case CHIPSET_NV34:
753                case CHIPSET_NV35:
754                case CHIPSET_NV36:
755                case CHIPSET_NV40:
756                case CHIPSET_NV41:
757                case 0x0120:
758                case CHIPSET_NV43:
759                case CHIPSET_NV44:
760                case 0x0130:
761                case CHIPSET_G72:
762                case CHIPSET_G70:
763                case CHIPSET_NV45:
764                case CHIPSET_NV44A:
765                case 0x0230:
766                case CHIPSET_G71:
767                case CHIPSET_G73:
768                case CHIPSET_C512:
769                    NVChipsets[numUsed].token = pciid;
770                    NVChipsets[numUsed].name = "Unknown NVIDIA chip";
771                    NVPciChipsets[numUsed].numChipset = pciid;
772                    NVPciChipsets[numUsed].PCIid = pciid;
773                    NVPciChipsets[numUsed].resList = RES_SHARED_VGA;
774                    numUsed++;
775                    break;
776                default:  break;  /* we don't recognize it */
777                }
778             }
779         }
780         ppPci++;
781     }
782
783     /* terminate the list */
784     NVChipsets[numUsed].token = -1;
785     NVChipsets[numUsed].name = NULL; 
786     NVPciChipsets[numUsed].numChipset = -1;
787     NVPciChipsets[numUsed].PCIid = -1;
788     NVPciChipsets[numUsed].resList = RES_UNDEFINED;
789
790     numUsed = xf86MatchPciInstances(NV_NAME, 0, NVChipsets, NVPciChipsets,
791                                     devSections, numDevSections, drv,
792                                     &usedChips);
793                         
794     if (numUsed <= 0) 
795         return FALSE;
796
797     if (flags & PROBE_DETECT)
798         foundScreen = TRUE;
799     else for (i = 0; i < numUsed; i++) {
800         pciVideoPtr pPci;
801
802         pPci = xf86GetPciInfoForEntity(usedChips[i]);
803         if(NVGetScrnInfoRec(NVPciChipsets, usedChips[i])) 
804             foundScreen = TRUE;
805     }
806
807     xfree(devSections);
808     xfree(usedChips);
809
810     return foundScreen;
811 }
812
813 /* Usually mandatory */
814 Bool
815 NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
816 {
817     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
818     NVPtr pNv = NVPTR(pScrn);
819     Bool ret = TRUE;
820
821     if (pNv->randr12_enable) {
822         NVFBLayout *pLayout = &pNv->CurrentLayout;
823         
824         if (pLayout->mode != mode) {
825                 if (!NVSetMode(pScrn, mode, RR_Rotate_0))
826                         ret = FALSE;
827         }
828
829         pLayout->mode = mode;
830         return ret;
831     } else 
832         return NVModeInit(xf86Screens[scrnIndex], mode);
833 }
834
835 /*
836  * This function is used to initialize the Start Address - the first
837  * displayed location in the video memory.
838  */
839 /* Usually mandatory */
840 void 
841 NVAdjustFrame(int scrnIndex, int x, int y, int flags)
842 {
843     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
844     int startAddr;
845     NVPtr pNv = NVPTR(pScrn);
846     NVFBLayout *pLayout = &pNv->CurrentLayout;
847
848     if (pNv->randr12_enable) {
849         xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
850         int startAddr;
851         xf86CrtcPtr crtc = config->output[config->compat_output]->crtc;
852         
853         if (crtc && crtc->enabled) {
854             NVCrtcSetBase(crtc, x, y);
855         }
856     } else {
857         startAddr = (((y*pLayout->displayWidth)+x)*(pLayout->bitsPerPixel/8));
858         startAddr += pNv->FB->offset;
859         NVSetStartAddress(pNv, startAddr);
860     }
861 }
862
863 void
864 NVResetCrtcConfig(ScrnInfoPtr pScrn, int set)
865 {
866         xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
867         NVPtr pNv = NVPTR(pScrn);
868         int i;
869         CARD32 val = 0;
870
871         for (i = 0; i < config->num_crtc; i++) {
872                 xf86CrtcPtr crtc = config->crtc[i];
873                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
874
875                 if (set) {
876                         NVCrtcRegPtr regp;
877
878                         regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
879                         val = regp->head;
880                 }
881
882                 nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_FSEL, val);
883         }
884 }
885
886 static Bool
887 NV50AcquireDisplay(ScrnInfoPtr pScrn)
888 {
889         if (!NV50DispInit(pScrn))
890                 return FALSE;
891         if (!NV50CursorAcquire(pScrn))
892                 return FALSE;
893         xf86SetDesiredModes(pScrn);
894
895         return TRUE;
896 }
897
898 static Bool
899 NV50ReleaseDisplay(ScrnInfoPtr pScrn)
900 {
901         NV50CursorRelease(pScrn);
902         NV50DispShutdown(pScrn);
903
904         return TRUE;
905 }
906
907 /*
908  * This is called when VT switching back to the X server.  Its job is
909  * to reinitialise the video mode.
910  *
911  * We may wish to unmap video/MMIO memory too.
912  */
913
914 /* Mandatory */
915 static Bool
916 NVEnterVT(int scrnIndex, int flags)
917 {
918     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
919     NVPtr pNv = NVPTR(pScrn);
920     
921     if (pNv->randr12_enable) { 
922         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
923         pScrn->vtSema = TRUE;
924
925         if (pNv->Architecture == NV_ARCH_50) {
926                 if (!NV50AcquireDisplay(pScrn))
927                         return FALSE;
928                 return TRUE;
929         }
930
931         /* Save the current state */
932         if (pNv->SaveGeneration != serverGeneration) {
933                 pNv->SaveGeneration = serverGeneration;
934                 NVSave(pScrn);
935         }
936
937         NVResetCrtcConfig(pScrn, 0);
938         if (!xf86SetDesiredModes(pScrn))
939                 return FALSE;
940         NVResetCrtcConfig(pScrn, 1);
941
942     } else {
943         if (!NVModeInit(pScrn, pScrn->currentMode))
944             return FALSE;
945
946     }
947     NVAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
948     if(pNv->overlayAdaptor)
949         NVResetVideo(pScrn);
950     return TRUE;
951     
952 }
953
954 /*
955  * This is called when VT switching away from the X server.  Its job is
956  * to restore the previous (text) mode.
957  *
958  * We may wish to remap video/MMIO memory too.
959  */
960
961 /* Mandatory */
962 static void
963 NVLeaveVT(int scrnIndex, int flags)
964 {
965     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
966     NVPtr pNv = NVPTR(pScrn);
967
968     if (pNv->Architecture == NV_ARCH_50) {
969         NV50ReleaseDisplay(pScrn);
970         return;
971     }
972     NVSync(pScrn);
973     NVRestore(pScrn);
974     if (!pNv->randr12_enable)
975         NVLockUnlock(pNv, 1);
976 }
977
978
979
980 static void 
981 NVBlockHandler (
982     int i, 
983     pointer blockData, 
984     pointer pTimeout,
985     pointer pReadmask
986 )
987 {
988     ScreenPtr     pScreen = screenInfo.screens[i];
989     ScrnInfoPtr   pScrnInfo = xf86Screens[i];
990     NVPtr         pNv = NVPTR(pScrnInfo);
991
992     if (pNv->DMAKickoffCallback)
993         (*pNv->DMAKickoffCallback)(pNv);
994     
995     pScreen->BlockHandler = pNv->BlockHandler;
996     (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
997     pScreen->BlockHandler = NVBlockHandler;
998
999     if (pNv->VideoTimerCallback) 
1000         (*pNv->VideoTimerCallback)(pScrnInfo, currentTime.milliseconds);
1001
1002 }
1003
1004
1005 /*
1006  * This is called at the end of each server generation.  It restores the
1007  * original (text) mode.  It should also unmap the video memory, and free
1008  * any per-generation data allocated by the driver.  It should finish
1009  * by unwrapping and calling the saved CloseScreen function.
1010  */
1011
1012 /* Mandatory */
1013 static Bool
1014 NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
1015 {
1016     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1017     NVPtr pNv = NVPTR(pScrn);
1018
1019     if (pScrn->vtSema) {
1020         pScrn->vtSema = FALSE;
1021         if (pNv->Architecture == NV_ARCH_50) {
1022             NV50ReleaseDisplay(pScrn);
1023         } else {
1024             NVSync(pScrn);
1025             NVRestore(pScrn);
1026             if (!pNv->randr12_enable)
1027                 NVLockUnlock(pNv, 1);
1028         }
1029     }
1030
1031     NVUnmapMem(pScrn);
1032     vgaHWUnmapMem(pScrn);
1033     if (pNv->AccelInfoRec)
1034         XAADestroyInfoRec(pNv->AccelInfoRec);
1035     if (pNv->CursorInfoRec)
1036         xf86DestroyCursorInfoRec(pNv->CursorInfoRec);
1037     if (pNv->ShadowPtr)
1038         xfree(pNv->ShadowPtr);
1039     if (pNv->overlayAdaptor)
1040         xfree(pNv->overlayAdaptor);
1041     if (pNv->blitAdaptor)
1042         xfree(pNv->blitAdaptor);
1043
1044     pScrn->vtSema = FALSE;
1045     pScreen->CloseScreen = pNv->CloseScreen;
1046     pScreen->BlockHandler = pNv->BlockHandler;
1047     return (*pScreen->CloseScreen)(scrnIndex, pScreen);
1048 }
1049
1050 /* Free up any persistent data structures */
1051
1052 /* Optional */
1053 static void
1054 NVFreeScreen(int scrnIndex, int flags)
1055 {
1056     /*
1057      * This only gets called when a screen is being deleted.  It does not
1058      * get called routinely at the end of a server generation.
1059      */
1060     if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
1061         vgaHWFreeHWRec(xf86Screens[scrnIndex]);
1062     NVFreeRec(xf86Screens[scrnIndex]);
1063 }
1064
1065
1066 /* Checks if a mode is suitable for the selected chipset. */
1067
1068 /* Optional */
1069 static ModeStatus
1070 NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
1071 {
1072     NVPtr pNv = NVPTR(xf86Screens[scrnIndex]);
1073
1074     if(pNv->fpWidth && pNv->fpHeight)
1075       if((pNv->fpWidth < mode->HDisplay) || (pNv->fpHeight < mode->VDisplay))
1076         return (MODE_PANEL);
1077
1078     return (MODE_OK);
1079 }
1080
1081 static void
1082 nvProbeDDC(ScrnInfoPtr pScrn, int index)
1083 {
1084     vbeInfoPtr pVbe;
1085
1086     if (xf86LoadSubModule(pScrn, "vbe")) {
1087         pVbe = VBEInit(NULL,index);
1088         ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
1089         vbeFree(pVbe);
1090     }
1091 }
1092
1093
1094 Bool NVI2CInit(ScrnInfoPtr pScrn)
1095 {
1096     char *mod = "i2c";
1097
1098     if (xf86LoadSubModule(pScrn, mod)) {
1099         xf86LoaderReqSymLists(i2cSymbols,NULL);
1100
1101         mod = "ddc";
1102         if(xf86LoadSubModule(pScrn, mod)) {
1103             xf86LoaderReqSymLists(ddcSymbols, NULL);
1104             return NVDACi2cInit(pScrn);
1105         } 
1106     }
1107
1108     xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1109               "Couldn't load %s module.  DDC probing can't be done\n", mod);
1110
1111     return FALSE;
1112 }
1113
1114 static Bool NVPreInitDRI(ScrnInfoPtr pScrn)
1115 {
1116         NVPtr pNv = NVPTR(pScrn);
1117
1118         if (!NVDRIGetVersion(pScrn))
1119                 return FALSE;
1120
1121         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1122                 "[dri] Found DRI library version %d.%d.%d and kernel"
1123                 " module version %d.%d.%d\n",
1124                 pNv->pLibDRMVersion->version_major,
1125                 pNv->pLibDRMVersion->version_minor,
1126                 pNv->pLibDRMVersion->version_patchlevel,
1127                 pNv->pKernelDRMVersion->version_major,
1128                 pNv->pKernelDRMVersion->version_minor,
1129                 pNv->pKernelDRMVersion->version_patchlevel);
1130
1131         return TRUE;
1132 }
1133
1134
1135 static Bool
1136 nv_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
1137 {
1138         scrn->virtualX = width;
1139         scrn->virtualY = height;
1140         return TRUE;
1141 }
1142
1143 static const xf86CrtcConfigFuncsRec nv_xf86crtc_config_funcs = {
1144         nv_xf86crtc_resize
1145 };
1146
1147
1148 static Bool
1149 NVDetermineChipsetArch(ScrnInfoPtr pScrn)
1150 {
1151         NVPtr pNv = NVPTR(pScrn);
1152
1153         switch (pNv->Chipset & 0x0ff0) {
1154         case CHIPSET_NV03:      /* Riva128 */
1155                 pNv->Architecture = NV_ARCH_03;
1156                 break;
1157         case CHIPSET_NV04:      /* TNT/TNT2 */
1158                 pNv->Architecture = NV_ARCH_04;
1159                 break;
1160         case CHIPSET_NV10:      /* GeForce 256 */
1161         case CHIPSET_NV11:      /* GeForce2 MX */
1162         case CHIPSET_NV15:      /* GeForce2 */
1163         case CHIPSET_NV17:      /* GeForce4 MX */
1164         case CHIPSET_NV18:      /* GeForce4 MX (8x AGP) */
1165         case CHIPSET_NFORCE:    /* nForce */
1166         case CHIPSET_NFORCE2:   /* nForce2 */
1167                 pNv->Architecture = NV_ARCH_10;
1168                 break;
1169         case CHIPSET_NV20:      /* GeForce3 */
1170         case CHIPSET_NV25:      /* GeForce4 Ti */
1171         case CHIPSET_NV28:      /* GeForce4 Ti (8x AGP) */
1172                 pNv->Architecture = NV_ARCH_20;
1173                 break;
1174         case CHIPSET_NV30:      /* GeForceFX 5800 */
1175         case CHIPSET_NV31:      /* GeForceFX 5600 */
1176         case CHIPSET_NV34:      /* GeForceFX 5200 */
1177         case CHIPSET_NV35:      /* GeForceFX 5900 */
1178         case CHIPSET_NV36:      /* GeForceFX 5700 */
1179                 pNv->Architecture = NV_ARCH_30;
1180                 break;
1181         case CHIPSET_NV40:      /* GeForce 6800 */
1182         case CHIPSET_NV41:      /* GeForce 6800 */
1183         case 0x0120:            /* GeForce 6800 */
1184         case CHIPSET_NV43:      /* GeForce 6600 */
1185         case CHIPSET_NV44:      /* GeForce 6200 */
1186         case CHIPSET_G72:       /* GeForce 7200, 7300, 7400 */
1187         case CHIPSET_G70:       /* GeForce 7800 */
1188         case CHIPSET_NV45:      /* GeForce 6800 */
1189         case CHIPSET_NV44A:     /* GeForce 6200 */
1190         case CHIPSET_G71:       /* GeForce 7900 */
1191         case CHIPSET_G73:       /* GeForce 7600 */
1192         case CHIPSET_C51:       /* GeForce 6100 */
1193         case CHIPSET_C512:      /* Geforce 6100 (nForce 4xx) */
1194                 pNv->Architecture = NV_ARCH_40;
1195                 break;
1196         case CHIPSET_NV50:
1197         case CHIPSET_NV84:
1198                 pNv->Architecture = NV_ARCH_50;
1199                 break;
1200         default:                /* Unknown, probably >=NV40 */
1201                 pNv->Architecture = NV_ARCH_40;
1202                 break;
1203         }
1204
1205         return TRUE;
1206 }
1207
1208 #define NVPreInitFail(fmt, args...) do {                                    \
1209         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%d: "fmt, __LINE__, ##args); \
1210         if (pNv->pInt10)                                                    \
1211                 xf86FreeInt10(pNv->pInt10);                                 \
1212         NVFreeRec(pScrn);                                                   \
1213         return FALSE;                                                       \
1214 } while(0)
1215
1216 /* Mandatory */
1217 Bool
1218 NVPreInit(ScrnInfoPtr pScrn, int flags)
1219 {
1220     xf86CrtcConfigPtr xf86_config;
1221     NVPtr pNv;
1222     MessageType from;
1223     int i, max_width, max_height;
1224     ClockRangePtr clockRanges;
1225     const char *s;
1226     int config_mon_rates = FALSE;
1227     int num_crtc;
1228
1229     if (flags & PROBE_DETECT) {
1230         EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
1231
1232         if (!pEnt)
1233             return FALSE;
1234
1235         i = pEnt->index;
1236         xfree(pEnt);
1237
1238         nvProbeDDC(pScrn, i);
1239         return TRUE;
1240     }
1241
1242     /*
1243      * Note: This function is only called once at server startup, and
1244      * not at the start of each server generation.  This means that
1245      * only things that are persistent across server generations can
1246      * be initialised here.  xf86Screens[] is (pScrn is a pointer to one
1247      * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()  
1248      * are too, and should be used for data that must persist across
1249      * server generations.
1250      *
1251      * Per-generation data should be allocated with
1252      * AllocateScreenPrivateIndex() from the ScreenInit() function.
1253      */
1254
1255     /* Check the number of entities, and fail if it isn't one. */
1256     if (pScrn->numEntities != 1)
1257         return FALSE;
1258
1259     /* Allocate the NVRec driverPrivate */
1260     if (!NVGetRec(pScrn)) {
1261         return FALSE;
1262     }
1263     pNv = NVPTR(pScrn);
1264
1265     /* Get the entity, and make sure it is PCI. */
1266     pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
1267     if (pNv->pEnt->location.type != BUS_PCI)
1268         return FALSE;
1269  
1270     /* Find the PCI info for this screen */
1271     pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index);
1272     pNv->PciTag = pciTag(pNv->PciInfo->bus, pNv->PciInfo->device,
1273                           pNv->PciInfo->func);
1274
1275     pNv->Primary = xf86IsPrimaryPci(pNv->PciInfo);
1276
1277     /* Initialize the card through int10 interface if needed */
1278     if (xf86LoadSubModule(pScrn, "int10")) {
1279         xf86LoaderReqSymLists(int10Symbols, NULL);
1280 #if !defined(__alpha__) && !defined(__powerpc__)
1281         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");
1282         pNv->pInt10 = xf86InitInt10(pNv->pEnt->index);
1283 #endif
1284     }
1285    
1286     xf86SetOperatingState(resVgaIo, pNv->pEnt->index, ResUnusedOpr);
1287     xf86SetOperatingState(resVgaMem, pNv->pEnt->index, ResDisableOpr);
1288
1289     /* Set pScrn->monitor */
1290     pScrn->monitor = pScrn->confScreen->monitor;
1291
1292     /*
1293      * Set the Chipset and ChipRev, allowing config file entries to
1294      * override.
1295      */
1296     if (pNv->pEnt->device->chipset && *pNv->pEnt->device->chipset) {
1297         pScrn->chipset = pNv->pEnt->device->chipset;
1298         pNv->Chipset = xf86StringToToken(NVKnownChipsets, pScrn->chipset);
1299         from = X_CONFIG;
1300     } else if (pNv->pEnt->device->chipID >= 0) {
1301         pNv->Chipset = pNv->pEnt->device->chipID;
1302         pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, 
1303                                                    pNv->Chipset);
1304         from = X_CONFIG;
1305         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
1306                    pNv->Chipset);
1307     } else {
1308         from = X_PROBED;
1309         pNv->Chipset = (pNv->PciInfo->vendor << 16) | pNv->PciInfo->chipType;
1310
1311         if(((pNv->Chipset & 0xfff0) == CHIPSET_MISC_BRIDGED) ||
1312            ((pNv->Chipset & 0xfff0) == CHIPSET_G73_BRIDGED))
1313         {
1314             pNv->Chipset = NVGetPCIXpressChip(pNv->PciInfo);
1315         }
1316
1317         pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, 
1318                                                    pNv->Chipset);
1319         if(!pScrn->chipset)
1320           pScrn->chipset = "Unknown NVIDIA chipset";
1321     }
1322
1323     if (pNv->pEnt->device->chipRev >= 0) {
1324         pNv->ChipRev = pNv->pEnt->device->chipRev;
1325         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
1326                    pNv->ChipRev);
1327     } else {
1328         pNv->ChipRev = pNv->PciInfo->chipRev;
1329     }
1330
1331     /*
1332      * This shouldn't happen because such problems should be caught in
1333      * NVProbe(), but check it just in case.
1334      */
1335     if (pScrn->chipset == NULL)
1336         NVPreInitFail("ChipID 0x%04X is not recognised\n", pNv->Chipset);
1337
1338     if (pNv->Chipset < 0)
1339         NVPreInitFail("Chipset \"%s\" is not recognised\n", pScrn->chipset);
1340
1341     xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
1342     NVDetermineChipsetArch(pScrn);
1343
1344     /*
1345      * The first thing we should figure out is the depth, bpp, etc.
1346      */
1347
1348     if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
1349         NVPreInitFail("\n");
1350     } else {
1351         /* Check that the returned depth is one we support */
1352         switch (pScrn->depth) {
1353             case 8:
1354             case 15:
1355             case 16:
1356             case 24:
1357                 /* OK */
1358                 break;
1359             default:
1360                 NVPreInitFail("Given depth (%d) is not supported by this driver\n",
1361                               pScrn->depth);
1362         }
1363     }
1364     xf86PrintDepthBpp(pScrn);
1365
1366     /* Get the depth24 pixmap format */
1367     if (pScrn->depth == 24 && pix24bpp == 0)
1368         pix24bpp = xf86GetBppFromDepth(pScrn, 24);
1369
1370     /*
1371      * This must happen after pScrn->display has been set because
1372      * xf86SetWeight references it.
1373      */
1374     if (pScrn->depth > 8) {
1375         /* The defaults are OK for us */
1376         rgb zeros = {0, 0, 0};
1377
1378         if (!xf86SetWeight(pScrn, zeros, zeros)) {
1379             NVPreInitFail("\n");
1380         }
1381     }
1382
1383     if (!xf86SetDefaultVisual(pScrn, -1)) {
1384         NVPreInitFail("\n");
1385     } else {
1386         /* We don't currently support DirectColor at > 8bpp */
1387         if (pScrn->depth > 8 && (pScrn->defaultVisual != TrueColor)) {
1388             NVPreInitFail("Given default visual"
1389                        " (%s) is not supported at depth %d\n",
1390                        xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
1391             
1392         }
1393     }
1394
1395     /* The vgahw module should be loaded here when needed */
1396     if (!xf86LoadSubModule(pScrn, "vgahw")) {
1397         NVPreInitFail("\n");
1398     }
1399     
1400     xf86LoaderReqSymLists(vgahwSymbols, NULL);
1401
1402     /*
1403      * Allocate a vgaHWRec
1404      */
1405     if (!vgaHWGetHWRec(pScrn)) {
1406         NVPreInitFail("\n");
1407     }
1408     
1409     /* We use a programmable clock */
1410     pScrn->progClock = TRUE;
1411
1412     /* Collect all of the relevant option flags (fill in pScrn->options) */
1413     xf86CollectOptions(pScrn, NULL);
1414
1415     /* Process the options */
1416     if (!(pNv->Options = xalloc(sizeof(NVOptions))))
1417         return FALSE;
1418     memcpy(pNv->Options, NVOptions, sizeof(NVOptions));
1419     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options);
1420
1421     /* Set the bits per RGB for 8bpp mode */
1422     if (pScrn->depth == 8)
1423         pScrn->rgbBits = 8;
1424
1425     from = X_DEFAULT;
1426
1427     pNv->randr12_enable = FALSE;
1428     if (xf86ReturnOptValBool(pNv->Options, OPTION_RANDR12, FALSE)) {
1429         pNv->randr12_enable = TRUE;
1430     }
1431     xf86DrvMsg(pScrn->scrnIndex, from, "Randr1.2 support %sabled\n", pNv->randr12_enable ? "en" : "dis");
1432
1433     pNv->HWCursor = TRUE;
1434     /*
1435      * The preferred method is to use the "hw cursor" option as a tri-state
1436      * option, with the default set above.
1437      */
1438     if (xf86GetOptValBool(pNv->Options, OPTION_HW_CURSOR, &pNv->HWCursor)) {
1439         from = X_CONFIG;
1440     }
1441     /* For compatibility, accept this too (as an override) */
1442     if (xf86ReturnOptValBool(pNv->Options, OPTION_SW_CURSOR, FALSE)) {
1443         from = X_CONFIG;
1444         pNv->HWCursor = FALSE;
1445     }
1446     xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
1447                 pNv->HWCursor ? "HW" : "SW");
1448
1449     pNv->FpScale = TRUE;
1450     if (xf86GetOptValBool(pNv->Options, OPTION_FP_SCALE, &pNv->FpScale)) {
1451         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Flat panel scaling %s\n",
1452                    pNv->FpScale ? "on" : "off");
1453     }
1454     if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) {
1455         pNv->NoAccel = TRUE;
1456         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
1457     }
1458     if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) {
1459         pNv->ShadowFB = TRUE;
1460         pNv->NoAccel = TRUE;
1461         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1462                 "Using \"Shadow Framebuffer\" - acceleration disabled\n");
1463     }
1464     if (!pNv->NoAccel) {
1465         from = X_DEFAULT;
1466         pNv->useEXA = TRUE;
1467         if((s = (char *)xf86GetOptValString(pNv->Options, OPTION_ACCELMETHOD))) {
1468             if(!xf86NameCmp(s,"XAA")) {
1469                 from = X_CONFIG;
1470                 pNv->useEXA = FALSE;
1471             } else if(!xf86NameCmp(s,"EXA")) {
1472                 from = X_CONFIG;
1473                 pNv->useEXA = TRUE;
1474             }
1475         }
1476         xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration method\n", pNv->useEXA ? "EXA" : "XAA");
1477     } else {
1478         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
1479     }
1480     
1481     pNv->Rotate = 0;
1482     pNv->RandRRotation = FALSE;
1483     if ((s = xf86GetOptValString(pNv->Options, OPTION_ROTATE))) {
1484       if(!xf86NameCmp(s, "CW")) {
1485         pNv->ShadowFB = TRUE;
1486         pNv->NoAccel = TRUE;
1487         pNv->HWCursor = FALSE;
1488         pNv->Rotate = 1;
1489         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1490                 "Rotating screen clockwise - acceleration disabled\n");
1491       } else
1492       if(!xf86NameCmp(s, "CCW")) {
1493         pNv->ShadowFB = TRUE;
1494         pNv->NoAccel = TRUE;
1495         pNv->HWCursor = FALSE;
1496         pNv->Rotate = -1;
1497         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1498                 "Rotating screen counter clockwise - acceleration disabled\n");
1499       } else
1500       if(!xf86NameCmp(s, "RandR")) {
1501 #ifdef RANDR
1502         pNv->ShadowFB = TRUE;
1503         pNv->NoAccel = TRUE;
1504         pNv->HWCursor = FALSE;
1505         pNv->RandRRotation = TRUE;
1506         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1507                 "Using RandR rotation - acceleration disabled\n");
1508 #else
1509         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1510                 "This driver was not compiled with support for the Resize and "
1511                 "Rotate extension.  Cannot honor 'Option \"Rotate\" "
1512                 "\"RandR\"'.\n");
1513 #endif
1514       } else {
1515         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1516                 "\"%s\" is not a valid value for Option \"Rotate\"\n", s);
1517         xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
1518                 "Valid options are \"CW\", \"CCW\", and \"RandR\"\n");
1519       }
1520     }
1521
1522     if(xf86GetOptValInteger(pNv->Options, OPTION_VIDEO_KEY, &(pNv->videoKey))) {
1523         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
1524                                 pNv->videoKey);
1525     } else {
1526         pNv->videoKey =  (1 << pScrn->offset.red) | 
1527                           (1 << pScrn->offset.green) |
1528         (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue); 
1529     }
1530
1531     if (xf86GetOptValBool(pNv->Options, OPTION_FLAT_PANEL, &(pNv->FlatPanel))) {
1532         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "forcing %s usage\n",
1533                    pNv->FlatPanel ? "DFP" : "CRTC");
1534     } else {
1535         pNv->FlatPanel = -1;   /* autodetect later */
1536     }
1537
1538     pNv->FPDither = FALSE;
1539     if (xf86GetOptValBool(pNv->Options, OPTION_FP_DITHER, &(pNv->FPDither))) 
1540         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "enabling flat panel dither\n");
1541
1542     if (xf86GetOptValInteger(pNv->Options, OPTION_CRTC_NUMBER,
1543                              &pNv->CRTCnumber)) 
1544     {
1545         if((pNv->CRTCnumber < 0) || (pNv->CRTCnumber > 1)) {
1546            pNv->CRTCnumber = -1;
1547            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1548                       "Invalid CRTC number.  Must be 0 or 1\n");
1549         }
1550     } else {
1551         pNv->CRTCnumber = -1; /* autodetect later */
1552     }
1553
1554
1555     if (xf86GetOptValInteger(pNv->Options, OPTION_FP_TWEAK, 
1556                              &pNv->PanelTweak))
1557     {
1558         pNv->usePanelTweak = TRUE;
1559     } else {
1560         pNv->usePanelTweak = FALSE;
1561     }
1562     
1563     if (pNv->pEnt->device->MemBase != 0) {
1564         /* Require that the config file value matches one of the PCI values. */
1565         if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->MemBase)) {
1566             NVPreInitFail(
1567                 "MemBase 0x%08lX doesn't match any PCI base register.\n",
1568                 pNv->pEnt->device->MemBase);
1569         }
1570         pNv->VRAMPhysical = pNv->pEnt->device->MemBase;
1571         from = X_CONFIG;
1572     } else {
1573         if (pNv->PciInfo->memBase[1] != 0) {
1574             pNv->VRAMPhysical = pNv->PciInfo->memBase[1] & 0xff800000;
1575             from = X_PROBED;
1576         } else {
1577             NVPreInitFail("No valid FB address in PCI config space\n");
1578             return FALSE;
1579         }
1580     }
1581     xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
1582                (unsigned long)pNv->VRAMPhysical);
1583
1584     if (pNv->pEnt->device->IOBase != 0) {
1585         /* Require that the config file value matches one of the PCI values. */
1586         if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->IOBase)) {
1587             NVPreInitFail("IOBase 0x%08lX doesn't match any PCI base register.\n",
1588                           pNv->pEnt->device->IOBase);
1589         }
1590         pNv->IOAddress = pNv->pEnt->device->IOBase;
1591         from = X_CONFIG;
1592     } else {
1593         if (pNv->PciInfo->memBase[0] != 0) {
1594             pNv->IOAddress = pNv->PciInfo->memBase[0] & 0xffffc000;
1595             from = X_PROBED;
1596         } else {
1597             NVPreInitFail("No valid MMIO address in PCI config space\n");
1598         }
1599     }
1600     xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
1601                (unsigned long)pNv->IOAddress);
1602      
1603     if (xf86RegisterResources(pNv->pEnt->index, NULL, ResExclusive)) {
1604         NVPreInitFail("xf86RegisterResources() found resource conflicts\n");
1605     }
1606
1607     pNv->alphaCursor = (pNv->Architecture >= NV_ARCH_10) &&
1608                        ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10);
1609
1610     if (pNv->randr12_enable) {
1611         /* Allocate an xf86CrtcConfig */
1612         xf86CrtcConfigInit(pScrn, &nv_xf86crtc_config_funcs);
1613         xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1614         
1615         max_width = 16384;
1616         xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, 2048);
1617     }
1618
1619     if (NVPreInitDRI(pScrn) == FALSE) {
1620         NVPreInitFail("\n");
1621     }
1622
1623     if (!pNv->randr12_enable) {
1624         if ((pScrn->monitor->nHsync == 0) && 
1625             (pScrn->monitor->nVrefresh == 0))
1626             config_mon_rates = FALSE;
1627         else
1628             config_mon_rates = TRUE;
1629     }
1630
1631     NVCommonSetup(pScrn);
1632
1633     if (pNv->randr12_enable) {
1634         if (pNv->Architecture < NV_ARCH_50) {
1635             NVI2CInit(pScrn);
1636             
1637             num_crtc = pNv->twoHeads ? 2 : 1;
1638             for (i = 0; i < num_crtc; i++) {
1639                 nv_crtc_init(pScrn, i);
1640             }
1641             
1642             NvSetupOutputs(pScrn);
1643         } else {
1644             if (!NV50DispPreInit(pScrn))
1645                 NVPreInitFail("\n");
1646             if (!NV50CreateOutputs(pScrn))
1647                 NVPreInitFail("\n");
1648             NV50DispCreateCrtcs(pScrn);
1649         }
1650
1651         if (!xf86InitialConfiguration(pScrn, FALSE))
1652             NVPreInitFail("No valid modes.\n");
1653     }
1654
1655     pScrn->videoRam = pNv->RamAmountKBytes;
1656     xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kBytes\n",
1657                pScrn->videoRam);
1658         
1659     pNv->VRAMPhysicalSize = pScrn->videoRam * 1024;
1660
1661     /*
1662      * If the driver can do gamma correction, it should call xf86SetGamma()
1663      * here.
1664      */
1665
1666     {
1667         Gamma zeros = {0.0, 0.0, 0.0};
1668
1669         if (!xf86SetGamma(pScrn, zeros)) {
1670             NVPreInitFail("\n");
1671         }
1672     }
1673
1674     /*
1675      * Setup the ClockRanges, which describe what clock ranges are available,
1676      * and what sort of modes they can be used for.
1677      */
1678
1679     clockRanges = xnfcalloc(sizeof(ClockRange), 1);
1680     clockRanges->next = NULL;
1681     clockRanges->minClock = pNv->MinVClockFreqKHz;
1682     clockRanges->maxClock = pNv->MaxVClockFreqKHz;
1683     clockRanges->clockIndex = -1;               /* programmable */
1684     clockRanges->doubleScanAllowed = TRUE;
1685     if((pNv->Architecture == NV_ARCH_20) ||
1686          ((pNv->Architecture == NV_ARCH_10) && 
1687            ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10) &&
1688            ((pNv->Chipset & 0x0ff0) != CHIPSET_NV15)))
1689     {
1690        /* HW is broken */
1691        clockRanges->interlaceAllowed = FALSE;
1692     } else {
1693        clockRanges->interlaceAllowed = TRUE;
1694     }
1695
1696     if(pNv->FlatPanel == 1) {
1697        clockRanges->interlaceAllowed = FALSE;
1698        clockRanges->doubleScanAllowed = FALSE;
1699     }
1700
1701     if(pNv->Architecture < NV_ARCH_10) {
1702        max_width = (pScrn->bitsPerPixel > 16) ? 2032 : 2048;
1703        max_height = 2048;
1704     } else {
1705        max_width = (pScrn->bitsPerPixel > 16) ? 4080 : 4096;
1706        max_height = 4096;
1707     }
1708
1709 #ifdef M_T_DRIVER
1710     /* If DFP, add a modeline corresponding to its panel size */
1711     if (pNv->FlatPanel && !pNv->Television && pNv->fpWidth && pNv->fpHeight) {
1712         DisplayModePtr Mode;
1713
1714         Mode = xnfcalloc(1, sizeof(DisplayModeRec));
1715         Mode = xf86CVTMode(pNv->fpWidth, pNv->fpHeight, 60.00, TRUE, FALSE);
1716         Mode->type = M_T_DRIVER;
1717         pScrn->monitor->Modes = xf86ModesAdd(pScrn->monitor->Modes, Mode);
1718
1719         if (!config_mon_rates) {
1720             if (!Mode->HSync)
1721                 Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal);
1722             if (!Mode->VRefresh)
1723                 Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) /
1724                     ((float) (Mode->HTotal * Mode->VTotal));
1725
1726             if (Mode->HSync < pScrn->monitor->hsync[0].lo)
1727                 pScrn->monitor->hsync[0].lo = Mode->HSync;
1728             if (Mode->HSync > pScrn->monitor->hsync[0].hi)
1729                 pScrn->monitor->hsync[0].hi = Mode->HSync;
1730             if (Mode->VRefresh < pScrn->monitor->vrefresh[0].lo)
1731                 pScrn->monitor->vrefresh[0].lo = Mode->VRefresh;
1732             if (Mode->VRefresh > pScrn->monitor->vrefresh[0].hi)
1733                 pScrn->monitor->vrefresh[0].hi = Mode->VRefresh;
1734
1735             pScrn->monitor->nHsync = 1;
1736             pScrn->monitor->nVrefresh = 1;
1737         }
1738     }
1739 #endif
1740
1741     /*
1742      * xf86ValidateModes will check that the mode HTotal and VTotal values
1743      * don't exceed the chipset's limit if pScrn->maxHValue and
1744      * pScrn->maxVValue are set.  Since our NVValidMode() already takes
1745      * care of this, we don't worry about setting them here.
1746      */
1747     i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
1748                           pScrn->display->modes, clockRanges,
1749                           NULL, 256, max_width,
1750                           512, 128, max_height,
1751                           pScrn->display->virtualX,
1752                           pScrn->display->virtualY,
1753                           pNv->VRAMPhysicalSize / 2,
1754                           LOOKUP_BEST_REFRESH);
1755
1756     if (i == -1) {
1757         NVPreInitFail("\n");
1758     }
1759
1760     /* Prune the modes marked as invalid */
1761     xf86PruneDriverModes(pScrn);
1762
1763     if (i == 0 || pScrn->modes == NULL) {
1764         NVPreInitFail("No valid modes found\n");
1765     }
1766
1767     /*
1768      * Set the CRTC parameters for all of the modes based on the type
1769      * of mode, and the chipset's interlace requirements.
1770      *
1771      * Calling this is required if the mode->Crtc* values are used by the
1772      * driver and if the driver doesn't provide code to set them.  They
1773      * are not pre-initialised at all.
1774      */
1775     xf86SetCrtcForModes(pScrn, 0);
1776
1777     /* Set the current mode to the first in the list */
1778     pScrn->currentMode = pScrn->modes;
1779
1780     /* Print the list of modes being used */
1781     xf86PrintModes(pScrn);
1782
1783     /* Set display resolution */
1784     xf86SetDpi(pScrn, 0, 0);
1785
1786
1787     /*
1788      * XXX This should be taken into account in some way in the mode valdation
1789      * section.
1790      */
1791
1792     if (xf86LoadSubModule(pScrn, "fb") == NULL) {
1793         NVPreInitFail("\n");
1794     }
1795
1796     xf86LoaderReqSymLists(fbSymbols, NULL);
1797     
1798     /* Load XAA if needed */
1799     if (!pNv->NoAccel) {
1800         if (!xf86LoadSubModule(pScrn, pNv->useEXA ? "exa" : "xaa")) {
1801             NVPreInitFail("\n");
1802         }
1803         xf86LoaderReqSymLists(xaaSymbols, NULL);
1804     }
1805
1806     /* Load ramdac if needed */
1807     if (pNv->HWCursor) {
1808         if (!xf86LoadSubModule(pScrn, "ramdac")) {
1809             NVPreInitFail("\n");
1810         }
1811         xf86LoaderReqSymLists(ramdacSymbols, NULL);
1812     }
1813
1814     /* Load shadowfb if needed */
1815     if (pNv->ShadowFB) {
1816         if (!xf86LoadSubModule(pScrn, "shadowfb")) {
1817             NVPreInitFail("\n");
1818         }
1819         xf86LoaderReqSymLists(shadowSymbols, NULL);
1820     }
1821
1822     pNv->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
1823     pNv->CurrentLayout.depth = pScrn->depth;
1824     pNv->CurrentLayout.displayWidth = pScrn->displayWidth;
1825     pNv->CurrentLayout.weight.red = pScrn->weight.red;
1826     pNv->CurrentLayout.weight.green = pScrn->weight.green;
1827     pNv->CurrentLayout.weight.blue = pScrn->weight.blue;
1828     pNv->CurrentLayout.mode = pScrn->currentMode;
1829
1830     xf86FreeInt10(pNv->pInt10);
1831
1832     pNv->pInt10 = NULL;
1833     return TRUE;
1834 }
1835
1836
1837 /*
1838  * Map the framebuffer and MMIO memory.
1839  */
1840
1841 static Bool
1842 NVMapMem(ScrnInfoPtr pScrn)
1843 {
1844         NVPtr pNv = NVPTR(pScrn);
1845
1846         pNv->FB = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, pNv->VRAMPhysicalSize/2);
1847         if (!pNv->FB) {
1848                 ErrorF("Failed to allocate memory for framebuffer!\n");
1849                 return FALSE;
1850         }
1851         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1852                    "Allocated %dMiB VRAM for framebuffer + offscreen pixmaps\n",
1853                    (unsigned int)(pNv->FB->size >> 20));
1854
1855         /*XXX: have to get these after we've allocated something, otherwise
1856          *     they're uninitialised in the DRM!
1857          */
1858         pNv->VRAMSize     = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_FB_SIZE);
1859         pNv->VRAMPhysical = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_FB_PHYSICAL);
1860         pNv->AGPSize      = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_AGP_SIZE);
1861         pNv->AGPPhysical  = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_AGP_PHYSICAL);
1862         if ( ! pNv->AGPSize ) /*if no AGP*/
1863                 /*use PCI*/
1864                 pNv->SGPhysical  = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_PCI_PHYSICAL);
1865
1866         int gart_scratch_size;
1867
1868         if (pNv->AGPSize) {
1869                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1870                            "AGPGART: %dMiB available\n",
1871                            (unsigned int)(pNv->AGPSize >> 20));
1872
1873                 if (pNv->AGPSize > (16*1024*1024))
1874                         gart_scratch_size = 16*1024*1024;
1875                 else
1876                         gart_scratch_size = pNv->AGPSize;
1877
1878                 }
1879         else {
1880
1881                 gart_scratch_size = (4 << 20) - (1 << 18) ;
1882                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1883                            "GART: PCI DMA - using %dKiB\n", gart_scratch_size >> 10);
1884                 
1885         }
1886
1887         /*The DRM allocates AGP memory, PCI as a fallback */
1888         pNv->GARTScratch = NVAllocateMemory(pNv, NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI_ACCEPTABLE,
1889                                                         gart_scratch_size);
1890         if (!pNv->GARTScratch) {
1891                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1892                            "Unable to allocate GART memory\n");
1893         } else {
1894                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1895                            "GART: mapped %dMiB at %p, offset is %d\n",
1896                            (unsigned int)(pNv->GARTScratch->size >> 20),
1897                            pNv->GARTScratch->map, pNv->GARTScratch->offset);
1898         }
1899
1900
1901         pNv->Cursor = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, 64*1024);
1902         if (!pNv->Cursor) {
1903                 ErrorF("Failed to allocate memory for hardware cursor\n");
1904                 return FALSE;
1905         }
1906
1907         pNv->ScratchBuffer = NVAllocateMemory(pNv, NOUVEAU_MEM_FB,
1908                         pNv->Architecture <NV_ARCH_10 ? 8192 : 16384);
1909         if (!pNv->ScratchBuffer) {
1910                 ErrorF("Failed to allocate memory for scratch buffer\n");
1911                 return FALSE;
1912         }
1913
1914     return TRUE;
1915 }
1916
1917 /*
1918  * Unmap the framebuffer and MMIO memory.
1919  */
1920
1921 static Bool
1922 NVUnmapMem(ScrnInfoPtr pScrn)
1923 {
1924         NVPtr pNv = NVPTR(pScrn);
1925
1926         NVFreeMemory(pNv, pNv->FB);
1927         NVFreeMemory(pNv, pNv->ScratchBuffer);
1928         NVFreeMemory(pNv, pNv->Cursor);
1929
1930     return TRUE;
1931 }
1932
1933
1934 /*
1935  * Initialise a new mode. 
1936  */
1937
1938 static Bool
1939 NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1940 {
1941     vgaHWPtr hwp = VGAHWPTR(pScrn);
1942     vgaRegPtr vgaReg;
1943     NVPtr pNv = NVPTR(pScrn);
1944     NVRegPtr nvReg;
1945
1946     /* Initialise the ModeReg values */
1947     if (!vgaHWInit(pScrn, mode))
1948         return FALSE;
1949     pScrn->vtSema = TRUE;
1950
1951     vgaReg = &hwp->ModeReg;
1952     nvReg = &pNv->ModeReg;
1953
1954     if(!NVDACInit(pScrn, mode))
1955         return FALSE;
1956
1957     NVLockUnlock(pNv, 0);
1958     if(pNv->twoHeads) {
1959         nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, nvReg->crtcOwner);
1960         NVLockUnlock(pNv, 0);
1961     }
1962
1963     /* Program the registers */
1964     vgaHWProtect(pScrn, TRUE);
1965
1966     NVDACRestore(pScrn, vgaReg, nvReg, FALSE);
1967
1968 #if X_BYTE_ORDER == X_BIG_ENDIAN
1969     /* turn on LFB swapping */
1970     {
1971         unsigned char tmp;
1972
1973         tmp = nvReadVGA(pNv, NV_VGA_CRTCX_SWAPPING);
1974         tmp |= (1 << 7);
1975         nvWriteVGA(pNv, NV_VGA_CRTCX_SWAPPING, tmp);
1976     }
1977 #endif
1978
1979     NVResetGraphics(pScrn);
1980
1981     vgaHWProtect(pScrn, FALSE);
1982
1983     pNv->CurrentLayout.mode = mode;
1984
1985     return TRUE;
1986 }
1987
1988 /*
1989  * Restore the initial (text) mode.
1990  */
1991 static void 
1992 NVRestore(ScrnInfoPtr pScrn)
1993 {
1994     vgaHWPtr hwp = VGAHWPTR(pScrn);
1995     vgaRegPtr vgaReg = &hwp->SavedReg;
1996     NVPtr pNv = NVPTR(pScrn);
1997     NVRegPtr nvReg = &pNv->SavedReg;
1998
1999     NVLockUnlock(pNv, 0);
2000
2001     if(pNv->twoHeads) {
2002         nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->CRTCnumber * 0x3);
2003         NVLockUnlock(pNv, 0);
2004     }
2005
2006     /* Only restore text mode fonts/text for the primary card */
2007     vgaHWProtect(pScrn, TRUE);
2008     NVDACRestore(pScrn, vgaReg, nvReg, pNv->Primary);
2009     if(pNv->twoHeads) {
2010         nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->vtOWNER);
2011     }
2012     vgaHWProtect(pScrn, FALSE);
2013 }
2014
2015
2016 #define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
2017 #define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3)
2018
2019 static void
2020 NVLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
2021               LOCO * colors, VisualPtr pVisual)
2022 {
2023         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2024         int c;
2025         NVPtr pNv = NVPTR(pScrn);
2026         int i, index;
2027
2028         for (c = 0; c < xf86_config->num_crtc; c++) {
2029                 xf86CrtcPtr crtc = xf86_config->crtc[c];
2030                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
2031                 NVCrtcRegPtr regp;
2032
2033                 regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
2034
2035                 if (crtc->enabled == 0)
2036                         continue;
2037
2038                 switch (pNv->CurrentLayout.depth) {
2039                 case 15:
2040                         for (i = 0; i < numColors; i++) {
2041                                 index = indices[i];
2042                                 regp->DAC[MAKE_INDEX(index, 5) + 0] =
2043                                     colors[index].red;
2044                                 regp->DAC[MAKE_INDEX(index, 5) + 1] =
2045                                     colors[index].green;
2046                                 regp->DAC[MAKE_INDEX(index, 5) + 2] =
2047                                     colors[index].blue;
2048                         }
2049                         break;
2050                 case 16:
2051                         for (i = 0; i < numColors; i++) {
2052                                 index = indices[i];
2053                                 regp->DAC[MAKE_INDEX(index, 6) + 1] =
2054                                     colors[index].green;
2055                                 if (index < 32) {
2056                                         regp->DAC[MAKE_INDEX(index, 5) +
2057                                                   0] = colors[index].red;
2058                                         regp->DAC[MAKE_INDEX(index, 5) +
2059                                                   2] = colors[index].blue;
2060                                 }
2061                         }
2062                         break;
2063                 default:
2064                         for (i = 0; i < numColors; i++) {
2065                                 index = indices[i];
2066                                 regp->DAC[index * 3] = colors[index].red;
2067                                 regp->DAC[(index * 3) + 1] =
2068                                     colors[index].green;
2069                                 regp->DAC[(index * 3) + 2] =
2070                                     colors[index].blue;
2071                         }
2072                         break;
2073                 }
2074
2075                 NVCrtcLoadPalette(crtc);
2076         }
2077 }
2078
2079 //#define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
2080 #define COLOR(c) (unsigned int)(0x3fff * ((c)/255.0))
2081 static void
2082 NV50LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
2083                 LOCO * colors, VisualPtr pVisual)
2084 {
2085         NVPtr pNv = NVPTR(pScrn);
2086         int i, index;
2087         volatile struct {
2088                 unsigned short red, green, blue, unused;
2089         } *lut = (void *) pNv->CLUT->map;
2090
2091         switch (pScrn->depth) {
2092         case 15:
2093                 for (i = 0; i < numColors; i++) {
2094                         index = indices[i];
2095                         lut[DEPTH_SHIFT(index, 5)].red =
2096                             COLOR(colors[index].red);
2097                         lut[DEPTH_SHIFT(index, 5)].green =
2098                             COLOR(colors[index].green);
2099                         lut[DEPTH_SHIFT(index, 5)].blue =
2100                             COLOR(colors[index].blue);
2101                 }
2102                 break;
2103         case 16:
2104                 for (i = 0; i < numColors; i++) {
2105                         index = indices[i];
2106                         lut[DEPTH_SHIFT(index, 6)].green =
2107                             COLOR(colors[index].green);
2108                         if (index < 32) {
2109                                 lut[DEPTH_SHIFT(index, 5)].red =
2110                                     COLOR(colors[index].red);
2111                                 lut[DEPTH_SHIFT(index, 5)].blue =
2112                                     COLOR(colors[index].blue);
2113                         }
2114                 }
2115                 break;
2116         default:
2117                 for (i = 0; i < numColors; i++) {
2118                         index = indices[i];
2119                         lut[index].red = COLOR(colors[index].red);
2120                         lut[index].green = COLOR(colors[index].green);
2121                         lut[index].blue = COLOR(colors[index].blue);
2122                 }
2123                 break;
2124         }
2125 }
2126
2127
2128 static void NVBacklightEnable(NVPtr pNv,  Bool on)
2129 {
2130     /* This is done differently on each laptop.  Here we
2131        define the ones we know for sure. */
2132
2133 #if defined(__powerpc__)
2134     if((pNv->Chipset == 0x10DE0179) || 
2135        (pNv->Chipset == 0x10DE0189) || 
2136        (pNv->Chipset == 0x10DE0329))
2137     {
2138        /* NV17,18,34 Apple iMac, iBook, PowerBook */
2139       CARD32 tmp_pmc, tmp_pcrt;
2140       tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
2141       tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
2142       if(on) {
2143           tmp_pmc |= (1 << 31);
2144           tmp_pcrt |= 0x1;
2145       }
2146       nvWriteMC(pNv, 0x10F0, tmp_pmc);
2147       nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
2148     }
2149 #endif
2150     
2151     if(pNv->LVDS) {
2152        if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11)) {
2153            nvWriteMC(pNv, 0x130C, on ? 3 : 7);
2154        }
2155     } else {
2156        CARD32 fpcontrol;
2157
2158        fpcontrol = nvReadCurRAMDAC(pNv, 0x848) & 0xCfffffCC;
2159
2160        /* cut the TMDS output */
2161        if(on) fpcontrol |= pNv->fpSyncs;
2162        else fpcontrol |= 0x20000022;
2163
2164        nvWriteCurRAMDAC(pNv, 0x0848, fpcontrol);
2165     }
2166 }
2167
2168 static void
2169 NVDPMSSetLCD(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
2170 {
2171   NVPtr pNv = NVPTR(pScrn);
2172
2173   if (!pScrn->vtSema) return;
2174
2175   vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
2176
2177   switch (PowerManagementMode) {
2178   case DPMSModeStandby:  /* HSync: Off, VSync: On */
2179   case DPMSModeSuspend:  /* HSync: On, VSync: Off */
2180   case DPMSModeOff:      /* HSync: Off, VSync: Off */
2181     NVBacklightEnable(pNv, 0);
2182     break;
2183   case DPMSModeOn:       /* HSync: On, VSync: On */
2184     NVBacklightEnable(pNv, 1);
2185   default:
2186     break;
2187   }
2188 }
2189
2190
2191 static void
2192 NVDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
2193 {
2194   unsigned char crtc1A;
2195   vgaHWPtr hwp = VGAHWPTR(pScrn);
2196
2197   if (!pScrn->vtSema) return;
2198
2199   crtc1A = hwp->readCrtc(hwp, 0x1A) & ~0xC0;
2200
2201   switch (PowerManagementMode) {
2202   case DPMSModeStandby:  /* HSync: Off, VSync: On */
2203     crtc1A |= 0x80;
2204     break;
2205   case DPMSModeSuspend:  /* HSync: On, VSync: Off */
2206     crtc1A |= 0x40;
2207     break;
2208   case DPMSModeOff:      /* HSync: Off, VSync: Off */
2209     crtc1A |= 0xC0;
2210     break;
2211   case DPMSModeOn:       /* HSync: On, VSync: On */
2212   default:
2213     break;
2214   }
2215
2216   /* vgaHWDPMSSet will merely cut the dac output */
2217   vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
2218
2219   hwp->writeCrtc(hwp, 0x1A, crtc1A);
2220 }
2221
2222
2223 /* Mandatory */
2224
2225 /* This gets called at the start of each server generation */
2226
2227 static Bool
2228 NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
2229 {
2230     ScrnInfoPtr pScrn;
2231     vgaHWPtr hwp;
2232     NVPtr pNv;
2233     int ret;
2234     VisualPtr visual;
2235     unsigned char *FBStart;
2236     int width, height, displayWidth, offscreenHeight, shadowHeight;
2237     BoxRec AvailFBArea;
2238
2239     /* 
2240      * First get the ScrnInfoRec
2241      */
2242     pScrn = xf86Screens[pScreen->myNum];
2243
2244     hwp = VGAHWPTR(pScrn);
2245     pNv = NVPTR(pScrn);
2246
2247     /* Map the VGA memory when the primary video */
2248     if (pNv->Primary) {
2249         hwp->MapSize = 0x10000;
2250         if (!vgaHWMapMem(pScrn))
2251             return FALSE;
2252     }
2253     
2254     /* First init DRI/DRM */
2255     if (!NVDRIScreenInit(pScrn))
2256         return FALSE;
2257     
2258     ret = drmCommandNone(pNv->drm_fd, DRM_NOUVEAU_CARD_INIT);
2259     if (ret) {
2260         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2261                    "Error initialising the nouveau kernel module: %d\n",
2262                    ret);
2263         return FALSE;
2264     }
2265     
2266     /* Allocate and map memory areas we need */
2267     if (!NVMapMem(pScrn))
2268         return FALSE;
2269     
2270     if (!pNv->NoAccel) {
2271         /* Init DRM - Alloc FIFO */
2272         if (!NVInitDma(pScrn))
2273             return FALSE;
2274         
2275         /* setup graphics objects */
2276         if (!NVAccelCommonInit(pScrn))
2277             return FALSE;
2278     }
2279     
2280     if (!pNv->randr12_enable) {
2281         /* Save the current state */
2282         NVSave(pScrn);
2283         /* Initialise the first mode */
2284         if (!NVModeInit(pScrn, pScrn->currentMode))
2285             return FALSE;
2286
2287         /* Darken the screen for aesthetic reasons and set the viewport */
2288         
2289         NVSaveScreen(pScreen, SCREEN_SAVER_ON);
2290         pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
2291         
2292     } else {
2293         pScrn->memPhysBase = pNv->VRAMPhysical;
2294         pScrn->fbOffset = 0;
2295         
2296         if (!NVEnterVT(scrnIndex, 0))
2297             return FALSE;
2298     }
2299
2300
2301     /*
2302      * The next step is to setup the screen's visuals, and initialise the
2303      * framebuffer code.  In cases where the framebuffer's default
2304      * choices for things like visual layouts and bits per RGB are OK,
2305      * this may be as simple as calling the framebuffer's ScreenInit()
2306      * function.  If not, the visuals will need to be setup before calling
2307      * a fb ScreenInit() function and fixed up after.
2308      *
2309      * For most PC hardware at depths >= 8, the defaults that fb uses
2310      * are not appropriate.  In this driver, we fixup the visuals after.
2311      */
2312
2313     /*
2314      * Reset the visual list.
2315      */
2316     miClearVisualTypes();
2317
2318     /* Setup the visuals we support. */
2319
2320     if (!miSetVisualTypes(pScrn->depth, 
2321                           miGetDefaultVisualMask(pScrn->depth), 8,
2322                           pScrn->defaultVisual))
2323           return FALSE;
2324     if (!miSetPixmapDepths ()) return FALSE;
2325
2326     /*
2327      * Call the framebuffer layer's ScreenInit function, and fill in other
2328      * pScreen fields.
2329      */
2330
2331     width = pScrn->virtualX;
2332     height = pScrn->virtualY;
2333     displayWidth = pScrn->displayWidth;
2334
2335
2336     if(pNv->Rotate) {
2337         height = pScrn->virtualX;
2338         width = pScrn->virtualY;
2339     }
2340
2341     /* If RandR rotation is enabled, leave enough space in the
2342      * framebuffer for us to rotate the screen dimensions without
2343      * changing the pitch.
2344      */
2345     if(pNv->RandRRotation)
2346         shadowHeight = max(width, height);
2347     else
2348         shadowHeight = height;
2349
2350     if(pNv->ShadowFB) {
2351         pNv->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
2352         pNv->ShadowPtr = xalloc(pNv->ShadowPitch * shadowHeight);
2353         displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3);
2354         FBStart = pNv->ShadowPtr;
2355     } else {
2356         pNv->ShadowPtr = NULL;
2357         FBStart = pNv->FB->map;
2358     }
2359
2360     switch (pScrn->bitsPerPixel) {
2361         case 8:
2362         case 16:
2363         case 32:
2364             ret = fbScreenInit(pScreen, FBStart, width, height,
2365                                pScrn->xDpi, pScrn->yDpi,
2366                                displayWidth, pScrn->bitsPerPixel);
2367             break;
2368         default:
2369             xf86DrvMsg(scrnIndex, X_ERROR,
2370                        "Internal error: invalid bpp (%d) in NVScreenInit\n",
2371                        pScrn->bitsPerPixel);
2372             ret = FALSE;
2373             break;
2374     }
2375     if (!ret)
2376         return FALSE;
2377
2378     if (pScrn->bitsPerPixel > 8) {
2379         /* Fixup RGB ordering */
2380         visual = pScreen->visuals + pScreen->numVisuals;
2381         while (--visual >= pScreen->visuals) {
2382             if ((visual->class | DynamicClass) == DirectColor) {
2383                 visual->offsetRed = pScrn->offset.red;
2384                 visual->offsetGreen = pScrn->offset.green;
2385                 visual->offsetBlue = pScrn->offset.blue;
2386                 visual->redMask = pScrn->mask.red;
2387                 visual->greenMask = pScrn->mask.green;
2388                 visual->blueMask = pScrn->mask.blue;
2389             }
2390         }
2391     }
2392
2393     fbPictureInit (pScreen, 0, 0);
2394     
2395     xf86SetBlackWhitePixels(pScreen);
2396
2397     offscreenHeight = pNv->FB->size /
2398                      (pScrn->displayWidth * pScrn->bitsPerPixel >> 3);
2399     if(offscreenHeight > 32767)
2400         offscreenHeight = 32767;
2401
2402     if (!pNv->useEXA) {
2403         AvailFBArea.x1 = 0;
2404         AvailFBArea.y1 = 0;
2405         AvailFBArea.x2 = pScrn->displayWidth;
2406         AvailFBArea.y2 = offscreenHeight;
2407         xf86InitFBManager(pScreen, &AvailFBArea);
2408     }
2409     
2410     if (!pNv->NoAccel) {
2411         if (pNv->useEXA)
2412             NVExaInit(pScreen);
2413         else /* XAA */
2414             NVXaaInit(pScreen);
2415     }
2416     NVResetGraphics(pScrn);
2417     
2418     miInitializeBackingStore(pScreen);
2419     xf86SetBackingStore(pScreen);
2420     xf86SetSilkenMouse(pScreen);
2421
2422     /* Finish DRI init */
2423     NVDRIFinishScreenInit(pScrn);
2424
2425     /* Initialize software cursor.  
2426         Must precede creation of the default colormap */
2427     miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
2428
2429     /* Initialize HW cursor layer. 
2430         Must follow software cursor initialization*/
2431     if (pNv->HWCursor) { 
2432         if(!NVCursorInit(pScreen))
2433             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
2434                 "Hardware cursor initialization failed\n");
2435     }
2436
2437     /* Initialise default colourmap */
2438     if (!miCreateDefColormap(pScreen))
2439         return FALSE;
2440
2441     /* Initialize colormap layer.  
2442        Must follow initialization of the default colormap */
2443     if (!pNv->randr12_enable) {
2444         if(!xf86HandleColormaps(pScreen, 256, 8, NVDACLoadPalette,
2445                                 NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
2446             return FALSE;
2447     } else {
2448         if (pNv->Architecture < NV_ARCH_50) {
2449             if (!xf86HandleColormaps(pScreen, 256, 8, NVLoadPalette,
2450                                      NULL,
2451                                      CMAP_RELOAD_ON_MODE_SWITCH |
2452                                      CMAP_PALETTED_TRUECOLOR))
2453                 return FALSE;
2454         } else {
2455             if (!xf86HandleColormaps(pScreen, 256, 8, NV50LoadPalette,
2456                                      NULL, CMAP_PALETTED_TRUECOLOR))
2457                 return FALSE;
2458         }
2459     }
2460
2461     if (pNv->randr12_enable) {
2462         xf86DPMSInit(pScreen, xf86DPMSSet, 0);
2463         
2464         if (!xf86CrtcScreenInit(pScreen))
2465             return FALSE;
2466
2467         pNv->PointerMoved = pScrn->PointerMoved;
2468         pScrn->PointerMoved = NVPointerMoved;
2469     }
2470
2471     if(pNv->ShadowFB) {
2472         RefreshAreaFuncPtr refreshArea = NVRefreshArea;
2473
2474         if(pNv->Rotate || pNv->RandRRotation) {
2475            pNv->PointerMoved = pScrn->PointerMoved;
2476            if(pNv->Rotate)
2477                pScrn->PointerMoved = NVPointerMoved;
2478
2479            switch(pScrn->bitsPerPixel) {
2480                case 8:  refreshArea = NVRefreshArea8;   break;
2481                case 16: refreshArea = NVRefreshArea16;  break;
2482                case 32: refreshArea = NVRefreshArea32;  break;
2483            }
2484            if(!pNv->RandRRotation) {
2485                xf86DisableRandR();
2486                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2487                           "Driver rotation enabled, RandR disabled\n");
2488            }
2489         }
2490
2491         ShadowFBInit(pScreen, refreshArea);
2492     }
2493
2494     if (!pNv->randr12_enable) {
2495         if(pNv->FlatPanel)
2496             xf86DPMSInit(pScreen, NVDPMSSetLCD, 0);
2497         else
2498             xf86DPMSInit(pScreen, NVDPMSSet, 0);
2499     }
2500
2501     pScrn->memPhysBase = pNv->VRAMPhysical;
2502     pScrn->fbOffset = 0;
2503
2504     if(pNv->Rotate == 0 && !pNv->RandRRotation)
2505        NVInitVideo(pScreen);
2506
2507     pScreen->SaveScreen = NVSaveScreen;
2508
2509     /* Wrap the current CloseScreen function */
2510     pNv->CloseScreen = pScreen->CloseScreen;
2511     pScreen->CloseScreen = NVCloseScreen;
2512
2513     pNv->BlockHandler = pScreen->BlockHandler;
2514     pScreen->BlockHandler = NVBlockHandler;
2515
2516 #ifdef RANDR
2517     /* Install our DriverFunc.  We have to do it this way instead of using the
2518      * HaveDriverFuncs argument to xf86AddDriver, because InitOutput clobbers
2519      * pScrn->DriverFunc */
2520     if (!pNv->randr12_enable)
2521         pScrn->DriverFunc = NVDriverFunc;
2522 #endif
2523
2524     /* Report any unused options (only for the first generation) */
2525     if (serverGeneration == 1) {
2526         xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
2527     }
2528     return TRUE;
2529 }
2530
2531 static Bool
2532 NVSaveScreen(ScreenPtr pScreen, int mode)
2533 {
2534     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2535     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2536     NVPtr pNv = NVPTR(pScrn);
2537     int i;
2538     Bool on = xf86IsUnblank(mode);
2539     
2540     if (pNv->randr12_enable) {
2541         if (pScrn->vtSema) {
2542             for (i = 0; i < xf86_config->num_crtc; i++) {
2543                 
2544                 if (xf86_config->crtc[i]->enabled) {
2545                     NVCrtcBlankScreen(xf86_config->crtc[i],
2546                                       on);
2547                 }
2548             }
2549             
2550         }
2551         return TRUE;
2552     } else
2553         return vgaHWSaveScreen(pScreen, mode);
2554 }
2555
2556 static void
2557 NVSave(ScrnInfoPtr pScrn)
2558 {
2559     NVPtr pNv = NVPTR(pScrn);
2560     NVRegPtr nvReg = &pNv->SavedReg;
2561     vgaHWPtr pVga = VGAHWPTR(pScrn);
2562     vgaRegPtr vgaReg = &pVga->SavedReg;
2563     int i;
2564
2565     if (pNv->randr12_enable) {
2566         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2567         int vgaflags = VGA_SR_CMAP | VGA_SR_MODE;
2568         
2569         for (i = 0; i < xf86_config->num_crtc; i++) {
2570                 xf86_config->crtc[i]->funcs->save(xf86_config->crtc[i]);
2571         }
2572
2573         for (i = 0; i < xf86_config->num_output; i++) {
2574                 xf86_config->output[i]->funcs->save(xf86_config->
2575                                                     output[i]);
2576         }
2577
2578         vgaHWUnlock(pVga);
2579 #ifndef __powerpc__
2580         vgaflags |= VGA_SR_FONTS;
2581 #endif
2582         vgaHWSave(pScrn, vgaReg, vgaflags);
2583     } else {
2584         NVLockUnlock(pNv, 0);
2585         if(pNv->twoHeads) {
2586             nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->CRTCnumber * 0x3);
2587             NVLockUnlock(pNv, 0);
2588         }
2589         
2590         NVDACSave(pScrn, vgaReg, nvReg, pNv->Primary);
2591     }
2592 }
2593
2594 #ifdef RANDR
2595 static Bool
2596 NVRandRGetInfo(ScrnInfoPtr pScrn, Rotation *rotations)
2597 {
2598     NVPtr pNv = NVPTR(pScrn);
2599
2600     if(pNv->RandRRotation)
2601        *rotations = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_270;
2602     else
2603        *rotations = RR_Rotate_0;
2604
2605     return TRUE;
2606 }
2607
2608 static Bool
2609 NVRandRSetConfig(ScrnInfoPtr pScrn, xorgRRConfig *config)
2610 {
2611     NVPtr pNv = NVPTR(pScrn);
2612
2613     switch(config->rotation) {
2614         case RR_Rotate_0:
2615             pNv->Rotate = 0;
2616             pScrn->PointerMoved = pNv->PointerMoved;
2617             break;
2618
2619         case RR_Rotate_90:
2620             pNv->Rotate = -1;
2621             pScrn->PointerMoved = NVPointerMoved;
2622             break;
2623
2624         case RR_Rotate_270:
2625             pNv->Rotate = 1;
2626             pScrn->PointerMoved = NVPointerMoved;
2627             break;
2628
2629         default:
2630             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2631                     "Unexpected rotation in NVRandRSetConfig!\n");
2632             pNv->Rotate = 0;
2633             pScrn->PointerMoved = pNv->PointerMoved;
2634             return FALSE;
2635     }
2636
2637     return TRUE;
2638 }
2639
2640 static Bool
2641 NVDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer data)
2642 {
2643     switch(op) {
2644        case RR_GET_INFO:
2645           return NVRandRGetInfo(pScrn, (Rotation*)data);
2646        case RR_SET_CONFIG:
2647           return NVRandRSetConfig(pScrn, (xorgRRConfig*)data);
2648        default:
2649           return FALSE;
2650     }
2651
2652     return FALSE;
2653 }
2654 #endif