randr12: try and bring over most of the randr12 code into master
[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     startAddr = (((y*pLayout->displayWidth)+x)*(pLayout->bitsPerPixel/8));
849     startAddr += pNv->FB->offset;
850     NVSetStartAddress(pNv, startAddr);
851 }
852
853
854 /*
855  * This is called when VT switching back to the X server.  Its job is
856  * to reinitialise the video mode.
857  *
858  * We may wish to unmap video/MMIO memory too.
859  */
860
861 /* Mandatory */
862 static Bool
863 NVEnterVT(int scrnIndex, int flags)
864 {
865     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
866     NVPtr pNv = NVPTR(pScrn);
867
868     if (!NVModeInit(pScrn, pScrn->currentMode))
869         return FALSE;
870     NVAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
871
872     if(pNv->overlayAdaptor)
873         NVResetVideo(pScrn);
874     return TRUE;
875 }
876
877 /*
878  * This is called when VT switching away from the X server.  Its job is
879  * to restore the previous (text) mode.
880  *
881  * We may wish to remap video/MMIO memory too.
882  */
883
884 /* Mandatory */
885 static void
886 NVLeaveVT(int scrnIndex, int flags)
887 {
888     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
889     NVPtr pNv = NVPTR(pScrn);
890
891     NVSync(pScrn);
892     NVRestore(pScrn);
893     NVLockUnlock(pNv, 1);
894 }
895
896
897
898 static void 
899 NVBlockHandler (
900     int i, 
901     pointer blockData, 
902     pointer pTimeout,
903     pointer pReadmask
904 )
905 {
906     ScreenPtr     pScreen = screenInfo.screens[i];
907     ScrnInfoPtr   pScrnInfo = xf86Screens[i];
908     NVPtr         pNv = NVPTR(pScrnInfo);
909
910     if (pNv->DMAKickoffCallback)
911         (*pNv->DMAKickoffCallback)(pNv);
912     
913     pScreen->BlockHandler = pNv->BlockHandler;
914     (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
915     pScreen->BlockHandler = NVBlockHandler;
916
917     if (pNv->VideoTimerCallback) 
918         (*pNv->VideoTimerCallback)(pScrnInfo, currentTime.milliseconds);
919
920 }
921
922
923 /*
924  * This is called at the end of each server generation.  It restores the
925  * original (text) mode.  It should also unmap the video memory, and free
926  * any per-generation data allocated by the driver.  It should finish
927  * by unwrapping and calling the saved CloseScreen function.
928  */
929
930 /* Mandatory */
931 static Bool
932 NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
933 {
934     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
935     NVPtr pNv = NVPTR(pScrn);
936
937     if (pScrn->vtSema) {
938         pScrn->vtSema = FALSE;
939         NVSync(pScrn);
940         NVRestore(pScrn);
941         NVLockUnlock(pNv, 1);
942     }
943
944     NVUnmapMem(pScrn);
945     vgaHWUnmapMem(pScrn);
946     if (pNv->AccelInfoRec)
947         XAADestroyInfoRec(pNv->AccelInfoRec);
948     if (pNv->CursorInfoRec)
949         xf86DestroyCursorInfoRec(pNv->CursorInfoRec);
950     if (pNv->ShadowPtr)
951         xfree(pNv->ShadowPtr);
952     if (pNv->overlayAdaptor)
953         xfree(pNv->overlayAdaptor);
954     if (pNv->blitAdaptor)
955         xfree(pNv->blitAdaptor);
956
957     pScreen->CloseScreen = pNv->CloseScreen;
958     pScreen->BlockHandler = pNv->BlockHandler;
959     return (*pScreen->CloseScreen)(scrnIndex, pScreen);
960 }
961
962 /* Free up any persistent data structures */
963
964 /* Optional */
965 static void
966 NVFreeScreen(int scrnIndex, int flags)
967 {
968     /*
969      * This only gets called when a screen is being deleted.  It does not
970      * get called routinely at the end of a server generation.
971      */
972     if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
973         vgaHWFreeHWRec(xf86Screens[scrnIndex]);
974     NVFreeRec(xf86Screens[scrnIndex]);
975 }
976
977
978 /* Checks if a mode is suitable for the selected chipset. */
979
980 /* Optional */
981 static ModeStatus
982 NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
983 {
984     NVPtr pNv = NVPTR(xf86Screens[scrnIndex]);
985
986     if(pNv->fpWidth && pNv->fpHeight)
987       if((pNv->fpWidth < mode->HDisplay) || (pNv->fpHeight < mode->VDisplay))
988         return (MODE_PANEL);
989
990     return (MODE_OK);
991 }
992
993 static void
994 nvProbeDDC(ScrnInfoPtr pScrn, int index)
995 {
996     vbeInfoPtr pVbe;
997
998     if (xf86LoadSubModule(pScrn, "vbe")) {
999         pVbe = VBEInit(NULL,index);
1000         ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
1001         vbeFree(pVbe);
1002     }
1003 }
1004
1005
1006 Bool NVI2CInit(ScrnInfoPtr pScrn)
1007 {
1008     char *mod = "i2c";
1009
1010     if (xf86LoadSubModule(pScrn, mod)) {
1011         xf86LoaderReqSymLists(i2cSymbols,NULL);
1012
1013         mod = "ddc";
1014         if(xf86LoadSubModule(pScrn, mod)) {
1015             xf86LoaderReqSymLists(ddcSymbols, NULL);
1016             return NVDACi2cInit(pScrn);
1017         } 
1018     }
1019
1020     xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1021               "Couldn't load %s module.  DDC probing can't be done\n", mod);
1022
1023     return FALSE;
1024 }
1025
1026 static Bool NVPreInitDRI(ScrnInfoPtr pScrn)
1027 {
1028         NVPtr pNv = NVPTR(pScrn);
1029
1030         if (!NVDRIGetVersion(pScrn))
1031                 return FALSE;
1032
1033         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1034                 "[dri] Found DRI library version %d.%d.%d and kernel"
1035                 " module version %d.%d.%d\n",
1036                 pNv->pLibDRMVersion->version_major,
1037                 pNv->pLibDRMVersion->version_minor,
1038                 pNv->pLibDRMVersion->version_patchlevel,
1039                 pNv->pKernelDRMVersion->version_major,
1040                 pNv->pKernelDRMVersion->version_minor,
1041                 pNv->pKernelDRMVersion->version_patchlevel);
1042
1043         return TRUE;
1044 }
1045
1046
1047 static Bool
1048 nv_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
1049 {
1050         scrn->virtualX = width;
1051         scrn->virtualY = height;
1052         return TRUE;
1053 }
1054
1055 static const xf86CrtcConfigFuncsRec nv_xf86crtc_config_funcs = {
1056         nv_xf86crtc_resize
1057 };
1058
1059
1060 #define NVPreInitFail(fmt, args...) do {                                    \
1061         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%d: "fmt, __LINE__, ##args); \
1062         if (pNv->pInt10)                                                    \
1063                 xf86FreeInt10(pNv->pInt10);                                 \
1064         NVFreeRec(pScrn);                                                   \
1065         return FALSE;                                                       \
1066 } while(0)
1067
1068 /* Mandatory */
1069 Bool
1070 NVPreInit(ScrnInfoPtr pScrn, int flags)
1071 {
1072     xf86CrtcConfigPtr xf86_config;
1073     NVPtr pNv;
1074     MessageType from;
1075     int i, max_width, max_height;
1076     ClockRangePtr clockRanges;
1077     const char *s;
1078     int config_mon_rates = FALSE;
1079     int num_crtc;
1080
1081     if (flags & PROBE_DETECT) {
1082         EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
1083
1084         if (!pEnt)
1085             return FALSE;
1086
1087         i = pEnt->index;
1088         xfree(pEnt);
1089
1090         nvProbeDDC(pScrn, i);
1091         return TRUE;
1092     }
1093
1094     /*
1095      * Note: This function is only called once at server startup, and
1096      * not at the start of each server generation.  This means that
1097      * only things that are persistent across server generations can
1098      * be initialised here.  xf86Screens[] is (pScrn is a pointer to one
1099      * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()  
1100      * are too, and should be used for data that must persist across
1101      * server generations.
1102      *
1103      * Per-generation data should be allocated with
1104      * AllocateScreenPrivateIndex() from the ScreenInit() function.
1105      */
1106
1107     /* Check the number of entities, and fail if it isn't one. */
1108     if (pScrn->numEntities != 1)
1109         return FALSE;
1110
1111     /* Allocate the NVRec driverPrivate */
1112     if (!NVGetRec(pScrn)) {
1113         return FALSE;
1114     }
1115     pNv = NVPTR(pScrn);
1116
1117     /* Get the entity, and make sure it is PCI. */
1118     pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
1119     if (pNv->pEnt->location.type != BUS_PCI)
1120         return FALSE;
1121  
1122     /* Find the PCI info for this screen */
1123     pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index);
1124     pNv->PciTag = pciTag(pNv->PciInfo->bus, pNv->PciInfo->device,
1125                           pNv->PciInfo->func);
1126
1127     pNv->Primary = xf86IsPrimaryPci(pNv->PciInfo);
1128
1129     /* Initialize the card through int10 interface if needed */
1130     if (xf86LoadSubModule(pScrn, "int10")) {
1131         xf86LoaderReqSymLists(int10Symbols, NULL);
1132 #if !defined(__alpha__) && !defined(__powerpc__)
1133         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");
1134         pNv->pInt10 = xf86InitInt10(pNv->pEnt->index);
1135 #endif
1136     }
1137    
1138     xf86SetOperatingState(resVgaIo, pNv->pEnt->index, ResUnusedOpr);
1139     xf86SetOperatingState(resVgaMem, pNv->pEnt->index, ResDisableOpr);
1140
1141     /* Set pScrn->monitor */
1142     pScrn->monitor = pScrn->confScreen->monitor;
1143
1144     /*
1145      * Set the Chipset and ChipRev, allowing config file entries to
1146      * override.
1147      */
1148     if (pNv->pEnt->device->chipset && *pNv->pEnt->device->chipset) {
1149         pScrn->chipset = pNv->pEnt->device->chipset;
1150         pNv->Chipset = xf86StringToToken(NVKnownChipsets, pScrn->chipset);
1151         from = X_CONFIG;
1152     } else if (pNv->pEnt->device->chipID >= 0) {
1153         pNv->Chipset = pNv->pEnt->device->chipID;
1154         pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, 
1155                                                    pNv->Chipset);
1156         from = X_CONFIG;
1157         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
1158                    pNv->Chipset);
1159     } else {
1160         from = X_PROBED;
1161         pNv->Chipset = (pNv->PciInfo->vendor << 16) | pNv->PciInfo->chipType;
1162
1163         if(((pNv->Chipset & 0xfff0) == CHIPSET_MISC_BRIDGED) ||
1164            ((pNv->Chipset & 0xfff0) == CHIPSET_G73_BRIDGED))
1165         {
1166             pNv->Chipset = NVGetPCIXpressChip(pNv->PciInfo);
1167         }
1168
1169         pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, 
1170                                                    pNv->Chipset);
1171         if(!pScrn->chipset)
1172           pScrn->chipset = "Unknown NVIDIA chipset";
1173     }
1174
1175     if (pNv->pEnt->device->chipRev >= 0) {
1176         pNv->ChipRev = pNv->pEnt->device->chipRev;
1177         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
1178                    pNv->ChipRev);
1179     } else {
1180         pNv->ChipRev = pNv->PciInfo->chipRev;
1181     }
1182
1183     /*
1184      * This shouldn't happen because such problems should be caught in
1185      * NVProbe(), but check it just in case.
1186      */
1187     if (pScrn->chipset == NULL)
1188         NVPreInitFail("ChipID 0x%04X is not recognised\n", pNv->Chipset);
1189
1190     if (pNv->Chipset < 0)
1191         NVPreInitFail("Chipset \"%s\" is not recognised\n", pScrn->chipset);
1192
1193     xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
1194
1195
1196     /*
1197      * The first thing we should figure out is the depth, bpp, etc.
1198      */
1199
1200     if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
1201         NVPreInitFail("\n");
1202     } else {
1203         /* Check that the returned depth is one we support */
1204         switch (pScrn->depth) {
1205             case 8:
1206             case 15:
1207             case 16:
1208             case 24:
1209                 /* OK */
1210                 break;
1211             default:
1212                 NVPreInitFail("Given depth (%d) is not supported by this driver\n",
1213                               pScrn->depth);
1214         }
1215     }
1216     xf86PrintDepthBpp(pScrn);
1217
1218     /* Get the depth24 pixmap format */
1219     if (pScrn->depth == 24 && pix24bpp == 0)
1220         pix24bpp = xf86GetBppFromDepth(pScrn, 24);
1221
1222     /*
1223      * This must happen after pScrn->display has been set because
1224      * xf86SetWeight references it.
1225      */
1226     if (pScrn->depth > 8) {
1227         /* The defaults are OK for us */
1228         rgb zeros = {0, 0, 0};
1229
1230         if (!xf86SetWeight(pScrn, zeros, zeros)) {
1231             NVPreInitFail("\n");
1232         }
1233     }
1234
1235     if (!xf86SetDefaultVisual(pScrn, -1)) {
1236         NVPreInitFail("\n");
1237     } else {
1238         /* We don't currently support DirectColor at > 8bpp */
1239         if (pScrn->depth > 8 && (pScrn->defaultVisual != TrueColor)) {
1240             NVPreInitFail("Given default visual"
1241                        " (%s) is not supported at depth %d\n",
1242                        xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
1243             
1244         }
1245     }
1246
1247     /* The vgahw module should be loaded here when needed */
1248     if (!xf86LoadSubModule(pScrn, "vgahw")) {
1249         NVPreInitFail("\n");
1250     }
1251     
1252     xf86LoaderReqSymLists(vgahwSymbols, NULL);
1253
1254     /*
1255      * Allocate a vgaHWRec
1256      */
1257     if (!vgaHWGetHWRec(pScrn)) {
1258         NVPreInitFail("\n");
1259     }
1260     
1261     /* We use a programmable clock */
1262     pScrn->progClock = TRUE;
1263
1264     /* Collect all of the relevant option flags (fill in pScrn->options) */
1265     xf86CollectOptions(pScrn, NULL);
1266
1267     /* Process the options */
1268     if (!(pNv->Options = xalloc(sizeof(NVOptions))))
1269         return FALSE;
1270     memcpy(pNv->Options, NVOptions, sizeof(NVOptions));
1271     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options);
1272
1273     /* Set the bits per RGB for 8bpp mode */
1274     if (pScrn->depth == 8)
1275         pScrn->rgbBits = 8;
1276
1277     from = X_DEFAULT;
1278
1279     pNv->randr12_enable = FALSE;
1280     if (xf86ReturnOptValBool(pNv->Options, OPTION_RANDR12, FALSE)) {
1281         pNv->randr12_enable = TRUE;
1282     }
1283     xf86DrvMsg(pScrn->scrnIndex, from, "Randr1.2 support %sabled\n", pNv->randr12_enable ? "en" : "dis");
1284
1285     pNv->HWCursor = TRUE;
1286     /*
1287      * The preferred method is to use the "hw cursor" option as a tri-state
1288      * option, with the default set above.
1289      */
1290     if (xf86GetOptValBool(pNv->Options, OPTION_HW_CURSOR, &pNv->HWCursor)) {
1291         from = X_CONFIG;
1292     }
1293     /* For compatibility, accept this too (as an override) */
1294     if (xf86ReturnOptValBool(pNv->Options, OPTION_SW_CURSOR, FALSE)) {
1295         from = X_CONFIG;
1296         pNv->HWCursor = FALSE;
1297     }
1298     xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
1299                 pNv->HWCursor ? "HW" : "SW");
1300
1301     pNv->FpScale = TRUE;
1302     if (xf86GetOptValBool(pNv->Options, OPTION_FP_SCALE, &pNv->FpScale)) {
1303         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Flat panel scaling %s\n",
1304                    pNv->FpScale ? "on" : "off");
1305     }
1306     if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) {
1307         pNv->NoAccel = TRUE;
1308         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
1309     }
1310     if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) {
1311         pNv->ShadowFB = TRUE;
1312         pNv->NoAccel = TRUE;
1313         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1314                 "Using \"Shadow Framebuffer\" - acceleration disabled\n");
1315     }
1316     if (!pNv->NoAccel) {
1317         from = X_DEFAULT;
1318         pNv->useEXA = TRUE;
1319         if((s = (char *)xf86GetOptValString(pNv->Options, OPTION_ACCELMETHOD))) {
1320             if(!xf86NameCmp(s,"XAA")) {
1321                 from = X_CONFIG;
1322                 pNv->useEXA = FALSE;
1323             } else if(!xf86NameCmp(s,"EXA")) {
1324                 from = X_CONFIG;
1325                 pNv->useEXA = TRUE;
1326             }
1327         }
1328         xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration method\n", pNv->useEXA ? "EXA" : "XAA");
1329     } else {
1330         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
1331     }
1332     
1333     pNv->Rotate = 0;
1334     pNv->RandRRotation = FALSE;
1335     if ((s = xf86GetOptValString(pNv->Options, OPTION_ROTATE))) {
1336       if(!xf86NameCmp(s, "CW")) {
1337         pNv->ShadowFB = TRUE;
1338         pNv->NoAccel = TRUE;
1339         pNv->HWCursor = FALSE;
1340         pNv->Rotate = 1;
1341         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1342                 "Rotating screen clockwise - acceleration disabled\n");
1343       } else
1344       if(!xf86NameCmp(s, "CCW")) {
1345         pNv->ShadowFB = TRUE;
1346         pNv->NoAccel = TRUE;
1347         pNv->HWCursor = FALSE;
1348         pNv->Rotate = -1;
1349         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1350                 "Rotating screen counter clockwise - acceleration disabled\n");
1351       } else
1352       if(!xf86NameCmp(s, "RandR")) {
1353 #ifdef RANDR
1354         pNv->ShadowFB = TRUE;
1355         pNv->NoAccel = TRUE;
1356         pNv->HWCursor = FALSE;
1357         pNv->RandRRotation = TRUE;
1358         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1359                 "Using RandR rotation - acceleration disabled\n");
1360 #else
1361         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1362                 "This driver was not compiled with support for the Resize and "
1363                 "Rotate extension.  Cannot honor 'Option \"Rotate\" "
1364                 "\"RandR\"'.\n");
1365 #endif
1366       } else {
1367         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1368                 "\"%s\" is not a valid value for Option \"Rotate\"\n", s);
1369         xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
1370                 "Valid options are \"CW\", \"CCW\", and \"RandR\"\n");
1371       }
1372     }
1373
1374     if(xf86GetOptValInteger(pNv->Options, OPTION_VIDEO_KEY, &(pNv->videoKey))) {
1375         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
1376                                 pNv->videoKey);
1377     } else {
1378         pNv->videoKey =  (1 << pScrn->offset.red) | 
1379                           (1 << pScrn->offset.green) |
1380         (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue); 
1381     }
1382
1383     if (xf86GetOptValBool(pNv->Options, OPTION_FLAT_PANEL, &(pNv->FlatPanel))) {
1384         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "forcing %s usage\n",
1385                    pNv->FlatPanel ? "DFP" : "CRTC");
1386     } else {
1387         pNv->FlatPanel = -1;   /* autodetect later */
1388     }
1389
1390     pNv->FPDither = FALSE;
1391     if (xf86GetOptValBool(pNv->Options, OPTION_FP_DITHER, &(pNv->FPDither))) 
1392         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "enabling flat panel dither\n");
1393
1394     if (xf86GetOptValInteger(pNv->Options, OPTION_CRTC_NUMBER,
1395                              &pNv->CRTCnumber)) 
1396     {
1397         if((pNv->CRTCnumber < 0) || (pNv->CRTCnumber > 1)) {
1398            pNv->CRTCnumber = -1;
1399            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1400                       "Invalid CRTC number.  Must be 0 or 1\n");
1401         }
1402     } else {
1403         pNv->CRTCnumber = -1; /* autodetect later */
1404     }
1405
1406
1407     if (xf86GetOptValInteger(pNv->Options, OPTION_FP_TWEAK, 
1408                              &pNv->PanelTweak))
1409     {
1410         pNv->usePanelTweak = TRUE;
1411     } else {
1412         pNv->usePanelTweak = FALSE;
1413     }
1414     
1415     if (pNv->pEnt->device->MemBase != 0) {
1416         /* Require that the config file value matches one of the PCI values. */
1417         if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->MemBase)) {
1418             NVPreInitFail(
1419                 "MemBase 0x%08lX doesn't match any PCI base register.\n",
1420                 pNv->pEnt->device->MemBase);
1421         }
1422         pNv->VRAMPhysical = pNv->pEnt->device->MemBase;
1423         from = X_CONFIG;
1424     } else {
1425         if (pNv->PciInfo->memBase[1] != 0) {
1426             pNv->VRAMPhysical = pNv->PciInfo->memBase[1] & 0xff800000;
1427             from = X_PROBED;
1428         } else {
1429             NVPreInitFail("No valid FB address in PCI config space\n");
1430             return FALSE;
1431         }
1432     }
1433     xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
1434                (unsigned long)pNv->VRAMPhysical);
1435
1436     if (pNv->pEnt->device->IOBase != 0) {
1437         /* Require that the config file value matches one of the PCI values. */
1438         if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->IOBase)) {
1439             NVPreInitFail("IOBase 0x%08lX doesn't match any PCI base register.\n",
1440                           pNv->pEnt->device->IOBase);
1441         }
1442         pNv->IOAddress = pNv->pEnt->device->IOBase;
1443         from = X_CONFIG;
1444     } else {
1445         if (pNv->PciInfo->memBase[0] != 0) {
1446             pNv->IOAddress = pNv->PciInfo->memBase[0] & 0xffffc000;
1447             from = X_PROBED;
1448         } else {
1449             NVPreInitFail("No valid MMIO address in PCI config space\n");
1450         }
1451     }
1452     xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
1453                (unsigned long)pNv->IOAddress);
1454      
1455     if (xf86RegisterResources(pNv->pEnt->index, NULL, ResExclusive)) {
1456         NVPreInitFail("xf86RegisterResources() found resource conflicts\n");
1457     }
1458
1459     switch (pNv->Chipset & 0x0ff0) {
1460     case CHIPSET_NV04:   /* TNT/TNT2 */
1461          pNv->Architecture =  NV_ARCH_04;
1462          break;
1463     case CHIPSET_NV10:   /* GeForce 256 */
1464     case CHIPSET_NV11:   /* GeForce2 MX */
1465     case CHIPSET_NV15:   /* GeForce2 */
1466     case CHIPSET_NV17:   /* GeForce4 MX */
1467     case CHIPSET_NV18:   /* GeForce4 MX (8x AGP) */
1468     case CHIPSET_NFORCE: /* nForce */
1469     case CHIPSET_NFORCE2:/* nForce2 */
1470          pNv->Architecture =  NV_ARCH_10;
1471          break;
1472     case CHIPSET_NV20:   /* GeForce3 */
1473     case CHIPSET_NV25:   /* GeForce4 Ti */
1474     case CHIPSET_NV28:   /* GeForce4 Ti (8x AGP) */
1475          pNv->Architecture =  NV_ARCH_20;
1476          break;
1477     case CHIPSET_NV30:   /* GeForceFX 5800 */
1478     case CHIPSET_NV31:   /* GeForceFX 5600 */
1479     case CHIPSET_NV34:   /* GeForceFX 5200 */
1480     case CHIPSET_NV35:   /* GeForceFX 5900 */
1481     case CHIPSET_NV36:   /* GeForceFX 5700 */
1482          pNv->Architecture =  NV_ARCH_30;
1483          break;
1484     case CHIPSET_NV40:   /* GeForce 6800 */
1485     case CHIPSET_NV41:   /* GeForce 6800 */
1486     case 0x0120:   /* GeForce 6800 */
1487     case CHIPSET_NV43:   /* GeForce 6600 */
1488     case CHIPSET_NV44:   /* GeForce 6200 */
1489     case CHIPSET_G72:   /* GeForce 7200, 7300, 7400 */
1490     case CHIPSET_G70:   /* GeForce 7800 */
1491     case CHIPSET_NV45:   /* GeForce 6800 */
1492     case CHIPSET_NV44A:   /* GeForce 6200 */
1493     case CHIPSET_G71:   /* GeForce 7900 */
1494     case CHIPSET_G73:   /* GeForce 7600 */
1495     case CHIPSET_C51:   /* GeForce 6100 */
1496     case CHIPSET_C512: /* Geforce 6100 (nForce 4xx) */
1497          pNv->Architecture =  NV_ARCH_40;
1498          break;
1499     default:           /* Unknown, probably >=NV40 */
1500          pNv->Architecture =  NV_ARCH_40;
1501          break;
1502     }
1503
1504     pNv->alphaCursor = (pNv->Architecture >= NV_ARCH_10) &&
1505                        ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10);
1506
1507     if (pNv->randr12_enable) {
1508         /* Allocate an xf86CrtcConfig */
1509         xf86CrtcConfigInit(pScrn, &nv_xf86crtc_config_funcs);
1510         xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1511         
1512         max_width = 16384;
1513         xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, 2048);
1514     }
1515
1516     if (NVPreInitDRI(pScrn) == FALSE) {
1517         NVPreInitFail("\n");
1518     }
1519
1520     if (!pNv->randr12_enable) {
1521         if ((pScrn->monitor->nHsync == 0) && 
1522             (pScrn->monitor->nVrefresh == 0))
1523             config_mon_rates = FALSE;
1524         else
1525             config_mon_rates = TRUE;
1526     }
1527
1528     NVCommonSetup(pScrn);
1529
1530     if (pNv->randr12_enable) {
1531         if (pNv->Architecture < NV_ARCH_50) {
1532             NVI2CInit(pScrn);
1533             
1534             num_crtc = pNv->twoHeads ? 2 : 1;
1535             for (i = 0; i < num_crtc; i++) {
1536                 nv_crtc_init(pScrn, i);
1537             }
1538             
1539             NvSetupOutputs(pScrn);
1540         } else {
1541 #if 0
1542             if (!NV50DispPreInit(pScrn))
1543                 NVPreInitFail("\n");
1544             if (!NV50CreateOutputs(pScrn))
1545                 NVPreInitFail("\n");
1546             NV50DispCreateCrtcs(pScrn);
1547 #endif
1548         }
1549
1550         if (!xf86InitialConfiguration(pScrn, FALSE))
1551             NVPreInitFail("No valid modes.\n");
1552     }
1553
1554     pScrn->videoRam = pNv->RamAmountKBytes;
1555     xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kBytes\n",
1556                pScrn->videoRam);
1557         
1558     pNv->VRAMPhysicalSize = pScrn->videoRam * 1024;
1559
1560     /*
1561      * If the driver can do gamma correction, it should call xf86SetGamma()
1562      * here.
1563      */
1564
1565     {
1566         Gamma zeros = {0.0, 0.0, 0.0};
1567
1568         if (!xf86SetGamma(pScrn, zeros)) {
1569             NVPreInitFail("\n");
1570         }
1571     }
1572
1573     /*
1574      * Setup the ClockRanges, which describe what clock ranges are available,
1575      * and what sort of modes they can be used for.
1576      */
1577
1578     clockRanges = xnfcalloc(sizeof(ClockRange), 1);
1579     clockRanges->next = NULL;
1580     clockRanges->minClock = pNv->MinVClockFreqKHz;
1581     clockRanges->maxClock = pNv->MaxVClockFreqKHz;
1582     clockRanges->clockIndex = -1;               /* programmable */
1583     clockRanges->doubleScanAllowed = TRUE;
1584     if((pNv->Architecture == NV_ARCH_20) ||
1585          ((pNv->Architecture == NV_ARCH_10) && 
1586            ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10) &&
1587            ((pNv->Chipset & 0x0ff0) != CHIPSET_NV15)))
1588     {
1589        /* HW is broken */
1590        clockRanges->interlaceAllowed = FALSE;
1591     } else {
1592        clockRanges->interlaceAllowed = TRUE;
1593     }
1594
1595     if(pNv->FlatPanel == 1) {
1596        clockRanges->interlaceAllowed = FALSE;
1597        clockRanges->doubleScanAllowed = FALSE;
1598     }
1599
1600     if(pNv->Architecture < NV_ARCH_10) {
1601        max_width = (pScrn->bitsPerPixel > 16) ? 2032 : 2048;
1602        max_height = 2048;
1603     } else {
1604        max_width = (pScrn->bitsPerPixel > 16) ? 4080 : 4096;
1605        max_height = 4096;
1606     }
1607
1608 #ifdef M_T_DRIVER
1609     /* If DFP, add a modeline corresponding to its panel size */
1610     if (pNv->FlatPanel && !pNv->Television && pNv->fpWidth && pNv->fpHeight) {
1611         DisplayModePtr Mode;
1612
1613         Mode = xnfcalloc(1, sizeof(DisplayModeRec));
1614         Mode = xf86CVTMode(pNv->fpWidth, pNv->fpHeight, 60.00, TRUE, FALSE);
1615         Mode->type = M_T_DRIVER;
1616         pScrn->monitor->Modes = xf86ModesAdd(pScrn->monitor->Modes, Mode);
1617
1618         if (!config_mon_rates) {
1619             if (!Mode->HSync)
1620                 Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal);
1621             if (!Mode->VRefresh)
1622                 Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) /
1623                     ((float) (Mode->HTotal * Mode->VTotal));
1624
1625             if (Mode->HSync < pScrn->monitor->hsync[0].lo)
1626                 pScrn->monitor->hsync[0].lo = Mode->HSync;
1627             if (Mode->HSync > pScrn->monitor->hsync[0].hi)
1628                 pScrn->monitor->hsync[0].hi = Mode->HSync;
1629             if (Mode->VRefresh < pScrn->monitor->vrefresh[0].lo)
1630                 pScrn->monitor->vrefresh[0].lo = Mode->VRefresh;
1631             if (Mode->VRefresh > pScrn->monitor->vrefresh[0].hi)
1632                 pScrn->monitor->vrefresh[0].hi = Mode->VRefresh;
1633
1634             pScrn->monitor->nHsync = 1;
1635             pScrn->monitor->nVrefresh = 1;
1636         }
1637     }
1638 #endif
1639
1640     /*
1641      * xf86ValidateModes will check that the mode HTotal and VTotal values
1642      * don't exceed the chipset's limit if pScrn->maxHValue and
1643      * pScrn->maxVValue are set.  Since our NVValidMode() already takes
1644      * care of this, we don't worry about setting them here.
1645      */
1646     i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
1647                           pScrn->display->modes, clockRanges,
1648                           NULL, 256, max_width,
1649                           512, 128, max_height,
1650                           pScrn->display->virtualX,
1651                           pScrn->display->virtualY,
1652                           pNv->VRAMPhysicalSize / 2,
1653                           LOOKUP_BEST_REFRESH);
1654
1655     if (i == -1) {
1656         NVPreInitFail("\n");
1657     }
1658
1659     /* Prune the modes marked as invalid */
1660     xf86PruneDriverModes(pScrn);
1661
1662     if (i == 0 || pScrn->modes == NULL) {
1663         NVPreInitFail("No valid modes found\n");
1664     }
1665
1666     /*
1667      * Set the CRTC parameters for all of the modes based on the type
1668      * of mode, and the chipset's interlace requirements.
1669      *
1670      * Calling this is required if the mode->Crtc* values are used by the
1671      * driver and if the driver doesn't provide code to set them.  They
1672      * are not pre-initialised at all.
1673      */
1674     xf86SetCrtcForModes(pScrn, 0);
1675
1676     /* Set the current mode to the first in the list */
1677     pScrn->currentMode = pScrn->modes;
1678
1679     /* Print the list of modes being used */
1680     xf86PrintModes(pScrn);
1681
1682     /* Set display resolution */
1683     xf86SetDpi(pScrn, 0, 0);
1684
1685
1686     /*
1687      * XXX This should be taken into account in some way in the mode valdation
1688      * section.
1689      */
1690
1691     if (xf86LoadSubModule(pScrn, "fb") == NULL) {
1692         NVPreInitFail("\n");
1693     }
1694
1695     xf86LoaderReqSymLists(fbSymbols, NULL);
1696     
1697     /* Load XAA if needed */
1698     if (!pNv->NoAccel) {
1699         if (!xf86LoadSubModule(pScrn, pNv->useEXA ? "exa" : "xaa")) {
1700             NVPreInitFail("\n");
1701         }
1702         xf86LoaderReqSymLists(xaaSymbols, NULL);
1703     }
1704
1705     /* Load ramdac if needed */
1706     if (pNv->HWCursor) {
1707         if (!xf86LoadSubModule(pScrn, "ramdac")) {
1708             NVPreInitFail("\n");
1709         }
1710         xf86LoaderReqSymLists(ramdacSymbols, NULL);
1711     }
1712
1713     /* Load shadowfb if needed */
1714     if (pNv->ShadowFB) {
1715         if (!xf86LoadSubModule(pScrn, "shadowfb")) {
1716             NVPreInitFail("\n");
1717         }
1718         xf86LoaderReqSymLists(shadowSymbols, NULL);
1719     }
1720
1721     pNv->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
1722     pNv->CurrentLayout.depth = pScrn->depth;
1723     pNv->CurrentLayout.displayWidth = pScrn->displayWidth;
1724     pNv->CurrentLayout.weight.red = pScrn->weight.red;
1725     pNv->CurrentLayout.weight.green = pScrn->weight.green;
1726     pNv->CurrentLayout.weight.blue = pScrn->weight.blue;
1727     pNv->CurrentLayout.mode = pScrn->currentMode;
1728
1729     xf86FreeInt10(pNv->pInt10);
1730
1731     pNv->pInt10 = NULL;
1732     return TRUE;
1733 }
1734
1735
1736 /*
1737  * Map the framebuffer and MMIO memory.
1738  */
1739
1740 static Bool
1741 NVMapMem(ScrnInfoPtr pScrn)
1742 {
1743         NVPtr pNv = NVPTR(pScrn);
1744
1745         pNv->FB = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, pNv->VRAMPhysicalSize/2);
1746         if (!pNv->FB) {
1747                 ErrorF("Failed to allocate memory for framebuffer!\n");
1748                 return FALSE;
1749         }
1750         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1751                    "Allocated %dMiB VRAM for framebuffer + offscreen pixmaps\n",
1752                    (unsigned int)(pNv->FB->size >> 20));
1753
1754         /*XXX: have to get these after we've allocated something, otherwise
1755          *     they're uninitialised in the DRM!
1756          */
1757         pNv->VRAMSize     = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_FB_SIZE);
1758         pNv->VRAMPhysical = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_FB_PHYSICAL);
1759         pNv->AGPSize      = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_AGP_SIZE);
1760         pNv->AGPPhysical  = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_AGP_PHYSICAL);
1761         if ( ! pNv->AGPSize ) /*if no AGP*/
1762                 /*use PCI*/
1763                 pNv->SGPhysical  = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_PCI_PHYSICAL);
1764
1765         int gart_scratch_size;
1766
1767         if (pNv->AGPSize) {
1768                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1769                            "AGPGART: %dMiB available\n",
1770                            (unsigned int)(pNv->AGPSize >> 20));
1771
1772                 if (pNv->AGPSize > (16*1024*1024))
1773                         gart_scratch_size = 16*1024*1024;
1774                 else
1775                         gart_scratch_size = pNv->AGPSize;
1776
1777                 }
1778         else {
1779
1780                 gart_scratch_size = (4 << 20) - (1 << 18) ;
1781                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1782                            "GART: PCI DMA - using %dKiB\n", gart_scratch_size >> 10);
1783                 
1784         }
1785
1786         /*The DRM allocates AGP memory, PCI as a fallback */
1787         pNv->GARTScratch = NVAllocateMemory(pNv, NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI_ACCEPTABLE,
1788                                                         gart_scratch_size);
1789         if (!pNv->GARTScratch) {
1790                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1791                            "Unable to allocate GART memory\n");
1792         } else {
1793                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1794                            "GART: mapped %dMiB at %p, offset is %d\n",
1795                            (unsigned int)(pNv->GARTScratch->size >> 20),
1796                            pNv->GARTScratch->map, pNv->GARTScratch->offset);
1797         }
1798
1799
1800         pNv->Cursor = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, 64*1024);
1801         if (!pNv->Cursor) {
1802                 ErrorF("Failed to allocate memory for hardware cursor\n");
1803                 return FALSE;
1804         }
1805
1806         pNv->ScratchBuffer = NVAllocateMemory(pNv, NOUVEAU_MEM_FB,
1807                         pNv->Architecture <NV_ARCH_10 ? 8192 : 16384);
1808         if (!pNv->ScratchBuffer) {
1809                 ErrorF("Failed to allocate memory for scratch buffer\n");
1810                 return FALSE;
1811         }
1812
1813     return TRUE;
1814 }
1815
1816 /*
1817  * Unmap the framebuffer and MMIO memory.
1818  */
1819
1820 static Bool
1821 NVUnmapMem(ScrnInfoPtr pScrn)
1822 {
1823         NVPtr pNv = NVPTR(pScrn);
1824
1825         NVFreeMemory(pNv, pNv->FB);
1826         NVFreeMemory(pNv, pNv->ScratchBuffer);
1827         NVFreeMemory(pNv, pNv->Cursor);
1828
1829     return TRUE;
1830 }
1831
1832
1833 /*
1834  * Initialise a new mode. 
1835  */
1836
1837 static Bool
1838 NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1839 {
1840     vgaHWPtr hwp = VGAHWPTR(pScrn);
1841     vgaRegPtr vgaReg;
1842     NVPtr pNv = NVPTR(pScrn);
1843     NVRegPtr nvReg;
1844
1845     /* Initialise the ModeReg values */
1846     if (!vgaHWInit(pScrn, mode))
1847         return FALSE;
1848     pScrn->vtSema = TRUE;
1849
1850     vgaReg = &hwp->ModeReg;
1851     nvReg = &pNv->ModeReg;
1852
1853     if(!NVDACInit(pScrn, mode))
1854         return FALSE;
1855
1856     NVLockUnlock(pNv, 0);
1857     if(pNv->twoHeads) {
1858         nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, nvReg->crtcOwner);
1859         NVLockUnlock(pNv, 0);
1860     }
1861
1862     /* Program the registers */
1863     vgaHWProtect(pScrn, TRUE);
1864
1865     NVDACRestore(pScrn, vgaReg, nvReg, FALSE);
1866
1867 #if X_BYTE_ORDER == X_BIG_ENDIAN
1868     /* turn on LFB swapping */
1869     {
1870         unsigned char tmp;
1871
1872         tmp = nvReadVGA(pNv, NV_VGA_CRTCX_SWAPPING);
1873         tmp |= (1 << 7);
1874         nvWriteVGA(pNv, NV_VGA_CRTCX_SWAPPING, tmp);
1875     }
1876 #endif
1877
1878     NVResetGraphics(pScrn);
1879
1880     vgaHWProtect(pScrn, FALSE);
1881
1882     pNv->CurrentLayout.mode = mode;
1883
1884     return TRUE;
1885 }
1886
1887 /*
1888  * Restore the initial (text) mode.
1889  */
1890 static void 
1891 NVRestore(ScrnInfoPtr pScrn)
1892 {
1893     vgaHWPtr hwp = VGAHWPTR(pScrn);
1894     vgaRegPtr vgaReg = &hwp->SavedReg;
1895     NVPtr pNv = NVPTR(pScrn);
1896     NVRegPtr nvReg = &pNv->SavedReg;
1897
1898     NVLockUnlock(pNv, 0);
1899
1900     if(pNv->twoHeads) {
1901         nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->CRTCnumber * 0x3);
1902         NVLockUnlock(pNv, 0);
1903     }
1904
1905     /* Only restore text mode fonts/text for the primary card */
1906     vgaHWProtect(pScrn, TRUE);
1907     NVDACRestore(pScrn, vgaReg, nvReg, pNv->Primary);
1908     if(pNv->twoHeads) {
1909         nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->vtOWNER);
1910     }
1911     vgaHWProtect(pScrn, FALSE);
1912 }
1913
1914
1915 #define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
1916 #define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3)
1917
1918 static void
1919 NVLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
1920               LOCO * colors, VisualPtr pVisual)
1921 {
1922         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1923         int c;
1924         NVPtr pNv = NVPTR(pScrn);
1925         int i, index;
1926
1927         for (c = 0; c < xf86_config->num_crtc; c++) {
1928                 xf86CrtcPtr crtc = xf86_config->crtc[c];
1929                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1930                 NVCrtcRegPtr regp;
1931
1932                 regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
1933
1934                 if (crtc->enabled == 0)
1935                         continue;
1936
1937                 switch (pNv->CurrentLayout.depth) {
1938                 case 15:
1939                         for (i = 0; i < numColors; i++) {
1940                                 index = indices[i];
1941                                 regp->DAC[MAKE_INDEX(index, 5) + 0] =
1942                                     colors[index].red;
1943                                 regp->DAC[MAKE_INDEX(index, 5) + 1] =
1944                                     colors[index].green;
1945                                 regp->DAC[MAKE_INDEX(index, 5) + 2] =
1946                                     colors[index].blue;
1947                         }
1948                         break;
1949                 case 16:
1950                         for (i = 0; i < numColors; i++) {
1951                                 index = indices[i];
1952                                 regp->DAC[MAKE_INDEX(index, 6) + 1] =
1953                                     colors[index].green;
1954                                 if (index < 32) {
1955                                         regp->DAC[MAKE_INDEX(index, 5) +
1956                                                   0] = colors[index].red;
1957                                         regp->DAC[MAKE_INDEX(index, 5) +
1958                                                   2] = colors[index].blue;
1959                                 }
1960                         }
1961                         break;
1962                 default:
1963                         for (i = 0; i < numColors; i++) {
1964                                 index = indices[i];
1965                                 regp->DAC[index * 3] = colors[index].red;
1966                                 regp->DAC[(index * 3) + 1] =
1967                                     colors[index].green;
1968                                 regp->DAC[(index * 3) + 2] =
1969                                     colors[index].blue;
1970                         }
1971                         break;
1972                 }
1973
1974                 NVCrtcLoadPalette(crtc);
1975         }
1976 }
1977
1978 //#define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
1979 #define COLOR(c) (unsigned int)(0x3fff * ((c)/255.0))
1980 static void
1981 NV50LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
1982                 LOCO * colors, VisualPtr pVisual)
1983 {
1984         NVPtr pNv = NVPTR(pScrn);
1985         int i, index;
1986         volatile struct {
1987                 unsigned short red, green, blue, unused;
1988         } *lut = (void *) pNv->CLUT->map;
1989
1990         switch (pScrn->depth) {
1991         case 15:
1992                 for (i = 0; i < numColors; i++) {
1993                         index = indices[i];
1994                         lut[DEPTH_SHIFT(index, 5)].red =
1995                             COLOR(colors[index].red);
1996                         lut[DEPTH_SHIFT(index, 5)].green =
1997                             COLOR(colors[index].green);
1998                         lut[DEPTH_SHIFT(index, 5)].blue =
1999                             COLOR(colors[index].blue);
2000                 }
2001                 break;
2002         case 16:
2003                 for (i = 0; i < numColors; i++) {
2004                         index = indices[i];
2005                         lut[DEPTH_SHIFT(index, 6)].green =
2006                             COLOR(colors[index].green);
2007                         if (index < 32) {
2008                                 lut[DEPTH_SHIFT(index, 5)].red =
2009                                     COLOR(colors[index].red);
2010                                 lut[DEPTH_SHIFT(index, 5)].blue =
2011                                     COLOR(colors[index].blue);
2012                         }
2013                 }
2014                 break;
2015         default:
2016                 for (i = 0; i < numColors; i++) {
2017                         index = indices[i];
2018                         lut[index].red = COLOR(colors[index].red);
2019                         lut[index].green = COLOR(colors[index].green);
2020                         lut[index].blue = COLOR(colors[index].blue);
2021                 }
2022                 break;
2023         }
2024 }
2025
2026
2027 static void NVBacklightEnable(NVPtr pNv,  Bool on)
2028 {
2029     /* This is done differently on each laptop.  Here we
2030        define the ones we know for sure. */
2031
2032 #if defined(__powerpc__)
2033     if((pNv->Chipset == 0x10DE0179) || 
2034        (pNv->Chipset == 0x10DE0189) || 
2035        (pNv->Chipset == 0x10DE0329))
2036     {
2037        /* NV17,18,34 Apple iMac, iBook, PowerBook */
2038       CARD32 tmp_pmc, tmp_pcrt;
2039       tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
2040       tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
2041       if(on) {
2042           tmp_pmc |= (1 << 31);
2043           tmp_pcrt |= 0x1;
2044       }
2045       nvWriteMC(pNv, 0x10F0, tmp_pmc);
2046       nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
2047     }
2048 #endif
2049     
2050     if(pNv->LVDS) {
2051        if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11)) {
2052            nvWriteMC(pNv, 0x130C, on ? 3 : 7);
2053        }
2054     } else {
2055        CARD32 fpcontrol;
2056
2057        fpcontrol = nvReadCurRAMDAC(pNv, 0x848) & 0xCfffffCC;
2058
2059        /* cut the TMDS output */
2060        if(on) fpcontrol |= pNv->fpSyncs;
2061        else fpcontrol |= 0x20000022;
2062
2063        nvWriteCurRAMDAC(pNv, 0x0848, fpcontrol);
2064     }
2065 }
2066
2067 static void
2068 NVDPMSSetLCD(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
2069 {
2070   NVPtr pNv = NVPTR(pScrn);
2071
2072   if (!pScrn->vtSema) return;
2073
2074   vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
2075
2076   switch (PowerManagementMode) {
2077   case DPMSModeStandby:  /* HSync: Off, VSync: On */
2078   case DPMSModeSuspend:  /* HSync: On, VSync: Off */
2079   case DPMSModeOff:      /* HSync: Off, VSync: Off */
2080     NVBacklightEnable(pNv, 0);
2081     break;
2082   case DPMSModeOn:       /* HSync: On, VSync: On */
2083     NVBacklightEnable(pNv, 1);
2084   default:
2085     break;
2086   }
2087 }
2088
2089
2090 static void
2091 NVDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
2092 {
2093   unsigned char crtc1A;
2094   vgaHWPtr hwp = VGAHWPTR(pScrn);
2095
2096   if (!pScrn->vtSema) return;
2097
2098   crtc1A = hwp->readCrtc(hwp, 0x1A) & ~0xC0;
2099
2100   switch (PowerManagementMode) {
2101   case DPMSModeStandby:  /* HSync: Off, VSync: On */
2102     crtc1A |= 0x80;
2103     break;
2104   case DPMSModeSuspend:  /* HSync: On, VSync: Off */
2105     crtc1A |= 0x40;
2106     break;
2107   case DPMSModeOff:      /* HSync: Off, VSync: Off */
2108     crtc1A |= 0xC0;
2109     break;
2110   case DPMSModeOn:       /* HSync: On, VSync: On */
2111   default:
2112     break;
2113   }
2114
2115   /* vgaHWDPMSSet will merely cut the dac output */
2116   vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
2117
2118   hwp->writeCrtc(hwp, 0x1A, crtc1A);
2119 }
2120
2121
2122 /* Mandatory */
2123
2124 /* This gets called at the start of each server generation */
2125
2126 static Bool
2127 NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
2128 {
2129     ScrnInfoPtr pScrn;
2130     vgaHWPtr hwp;
2131     NVPtr pNv;
2132     int ret;
2133     VisualPtr visual;
2134     unsigned char *FBStart;
2135     int width, height, displayWidth, offscreenHeight, shadowHeight;
2136     BoxRec AvailFBArea;
2137
2138     /* 
2139      * First get the ScrnInfoRec
2140      */
2141     pScrn = xf86Screens[pScreen->myNum];
2142
2143     hwp = VGAHWPTR(pScrn);
2144     pNv = NVPTR(pScrn);
2145
2146     /* Map the VGA memory when the primary video */
2147     if (pNv->Primary) {
2148         hwp->MapSize = 0x10000;
2149         if (!vgaHWMapMem(pScrn))
2150             return FALSE;
2151     }
2152     
2153     /* First init DRI/DRM */
2154     if (!NVDRIScreenInit(pScrn))
2155         return FALSE;
2156     
2157     ret = drmCommandNone(pNv->drm_fd, DRM_NOUVEAU_CARD_INIT);
2158     if (ret) {
2159         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2160                    "Error initialising the nouveau kernel module: %d\n",
2161                    ret);
2162         return FALSE;
2163     }
2164     
2165     /* Allocate and map memory areas we need */
2166     if (!NVMapMem(pScrn))
2167         return FALSE;
2168     
2169     if (!pNv->NoAccel) {
2170         /* Init DRM - Alloc FIFO */
2171         if (!NVInitDma(pScrn))
2172             return FALSE;
2173         
2174         /* setup graphics objects */
2175         if (!NVAccelCommonInit(pScrn))
2176             return FALSE;
2177     }
2178     
2179     if (!pNv->randr12_enable) {
2180         /* Save the current state */
2181         NVSave(pScrn);
2182         /* Initialise the first mode */
2183         if (!NVModeInit(pScrn, pScrn->currentMode))
2184             return FALSE;
2185
2186         /* Darken the screen for aesthetic reasons and set the viewport */
2187         
2188         NVSaveScreen(pScreen, SCREEN_SAVER_ON);
2189         pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
2190         
2191     } else {
2192         pScrn->memPhysBase = pNv->VRAMPhysical;
2193         pScrn->fbOffset = 0;
2194         
2195         if (!NVEnterVT(scrnIndex, 0))
2196             return FALSE;
2197     }
2198
2199
2200     /*
2201      * The next step is to setup the screen's visuals, and initialise the
2202      * framebuffer code.  In cases where the framebuffer's default
2203      * choices for things like visual layouts and bits per RGB are OK,
2204      * this may be as simple as calling the framebuffer's ScreenInit()
2205      * function.  If not, the visuals will need to be setup before calling
2206      * a fb ScreenInit() function and fixed up after.
2207      *
2208      * For most PC hardware at depths >= 8, the defaults that fb uses
2209      * are not appropriate.  In this driver, we fixup the visuals after.
2210      */
2211
2212     /*
2213      * Reset the visual list.
2214      */
2215     miClearVisualTypes();
2216
2217     /* Setup the visuals we support. */
2218
2219     if (!miSetVisualTypes(pScrn->depth, 
2220                           miGetDefaultVisualMask(pScrn->depth), 8,
2221                           pScrn->defaultVisual))
2222           return FALSE;
2223     if (!miSetPixmapDepths ()) return FALSE;
2224
2225     /*
2226      * Call the framebuffer layer's ScreenInit function, and fill in other
2227      * pScreen fields.
2228      */
2229
2230     width = pScrn->virtualX;
2231     height = pScrn->virtualY;
2232     displayWidth = pScrn->displayWidth;
2233
2234
2235     if(pNv->Rotate) {
2236         height = pScrn->virtualX;
2237         width = pScrn->virtualY;
2238     }
2239
2240     /* If RandR rotation is enabled, leave enough space in the
2241      * framebuffer for us to rotate the screen dimensions without
2242      * changing the pitch.
2243      */
2244     if(pNv->RandRRotation)
2245         shadowHeight = max(width, height);
2246     else
2247         shadowHeight = height;
2248
2249     if(pNv->ShadowFB) {
2250         pNv->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
2251         pNv->ShadowPtr = xalloc(pNv->ShadowPitch * shadowHeight);
2252         displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3);
2253         FBStart = pNv->ShadowPtr;
2254     } else {
2255         pNv->ShadowPtr = NULL;
2256         FBStart = pNv->FB->map;
2257     }
2258
2259     switch (pScrn->bitsPerPixel) {
2260         case 8:
2261         case 16:
2262         case 32:
2263             ret = fbScreenInit(pScreen, FBStart, width, height,
2264                                pScrn->xDpi, pScrn->yDpi,
2265                                displayWidth, pScrn->bitsPerPixel);
2266             break;
2267         default:
2268             xf86DrvMsg(scrnIndex, X_ERROR,
2269                        "Internal error: invalid bpp (%d) in NVScreenInit\n",
2270                        pScrn->bitsPerPixel);
2271             ret = FALSE;
2272             break;
2273     }
2274     if (!ret)
2275         return FALSE;
2276
2277     if (pScrn->bitsPerPixel > 8) {
2278         /* Fixup RGB ordering */
2279         visual = pScreen->visuals + pScreen->numVisuals;
2280         while (--visual >= pScreen->visuals) {
2281             if ((visual->class | DynamicClass) == DirectColor) {
2282                 visual->offsetRed = pScrn->offset.red;
2283                 visual->offsetGreen = pScrn->offset.green;
2284                 visual->offsetBlue = pScrn->offset.blue;
2285                 visual->redMask = pScrn->mask.red;
2286                 visual->greenMask = pScrn->mask.green;
2287                 visual->blueMask = pScrn->mask.blue;
2288             }
2289         }
2290     }
2291
2292     fbPictureInit (pScreen, 0, 0);
2293     
2294     xf86SetBlackWhitePixels(pScreen);
2295
2296     offscreenHeight = pNv->FB->size /
2297                      (pScrn->displayWidth * pScrn->bitsPerPixel >> 3);
2298     if(offscreenHeight > 32767)
2299         offscreenHeight = 32767;
2300
2301     if (!pNv->useEXA) {
2302         AvailFBArea.x1 = 0;
2303         AvailFBArea.y1 = 0;
2304         AvailFBArea.x2 = pScrn->displayWidth;
2305         AvailFBArea.y2 = offscreenHeight;
2306         xf86InitFBManager(pScreen, &AvailFBArea);
2307     }
2308     
2309     if (!pNv->NoAccel) {
2310         if (pNv->useEXA)
2311             NVExaInit(pScreen);
2312         else /* XAA */
2313             NVXaaInit(pScreen);
2314     }
2315     NVResetGraphics(pScrn);
2316     
2317     miInitializeBackingStore(pScreen);
2318     xf86SetBackingStore(pScreen);
2319     xf86SetSilkenMouse(pScreen);
2320
2321     /* Finish DRI init */
2322     NVDRIFinishScreenInit(pScrn);
2323
2324     /* Initialize software cursor.  
2325         Must precede creation of the default colormap */
2326     miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
2327
2328     /* Initialize HW cursor layer. 
2329         Must follow software cursor initialization*/
2330     if (pNv->HWCursor) { 
2331         if(!NVCursorInit(pScreen))
2332             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
2333                 "Hardware cursor initialization failed\n");
2334     }
2335
2336     /* Initialise default colourmap */
2337     if (!miCreateDefColormap(pScreen))
2338         return FALSE;
2339
2340     /* Initialize colormap layer.  
2341        Must follow initialization of the default colormap */
2342     if (!pNv->randr12_enable) {
2343         if(!xf86HandleColormaps(pScreen, 256, 8, NVDACLoadPalette,
2344                                 NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
2345             return FALSE;
2346     } else {
2347         if (pNv->Architecture < NV_ARCH_50) {
2348             if (!xf86HandleColormaps(pScreen, 256, 8, NVLoadPalette,
2349                                      NULL,
2350                                      CMAP_RELOAD_ON_MODE_SWITCH |
2351                                      CMAP_PALETTED_TRUECOLOR))
2352                 return FALSE;
2353         } else {
2354             if (!xf86HandleColormaps(pScreen, 256, 8, NV50LoadPalette,
2355                                      NULL, CMAP_PALETTED_TRUECOLOR))
2356                 return FALSE;
2357         }
2358     }
2359
2360     if (pNv->randr12_enable) {
2361         xf86DPMSInit(pScreen, xf86DPMSSet, 0);
2362         
2363         if (!xf86CrtcScreenInit(pScreen))
2364             return FALSE;
2365
2366         pNv->PointerMoved = pScrn->PointerMoved;
2367         pScrn->PointerMoved = NVPointerMoved;
2368     }
2369
2370     if(pNv->ShadowFB) {
2371         RefreshAreaFuncPtr refreshArea = NVRefreshArea;
2372
2373         if(pNv->Rotate || pNv->RandRRotation) {
2374            pNv->PointerMoved = pScrn->PointerMoved;
2375            if(pNv->Rotate)
2376                pScrn->PointerMoved = NVPointerMoved;
2377
2378            switch(pScrn->bitsPerPixel) {
2379                case 8:  refreshArea = NVRefreshArea8;   break;
2380                case 16: refreshArea = NVRefreshArea16;  break;
2381                case 32: refreshArea = NVRefreshArea32;  break;
2382            }
2383            if(!pNv->RandRRotation) {
2384                xf86DisableRandR();
2385                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2386                           "Driver rotation enabled, RandR disabled\n");
2387            }
2388         }
2389
2390         ShadowFBInit(pScreen, refreshArea);
2391     }
2392
2393     if (!pNv->randr12_enable) {
2394         if(pNv->FlatPanel)
2395             xf86DPMSInit(pScreen, NVDPMSSetLCD, 0);
2396         else
2397             xf86DPMSInit(pScreen, NVDPMSSet, 0);
2398     }
2399
2400     pScrn->memPhysBase = pNv->VRAMPhysical;
2401     pScrn->fbOffset = 0;
2402
2403     if(pNv->Rotate == 0 && !pNv->RandRRotation)
2404        NVInitVideo(pScreen);
2405
2406     pScreen->SaveScreen = NVSaveScreen;
2407
2408     /* Wrap the current CloseScreen function */
2409     pNv->CloseScreen = pScreen->CloseScreen;
2410     pScreen->CloseScreen = NVCloseScreen;
2411
2412     pNv->BlockHandler = pScreen->BlockHandler;
2413     pScreen->BlockHandler = NVBlockHandler;
2414
2415 #ifdef RANDR
2416     /* Install our DriverFunc.  We have to do it this way instead of using the
2417      * HaveDriverFuncs argument to xf86AddDriver, because InitOutput clobbers
2418      * pScrn->DriverFunc */
2419     if (!pNv->randr12_enable)
2420         pScrn->DriverFunc = NVDriverFunc;
2421 #endif
2422
2423     /* Report any unused options (only for the first generation) */
2424     if (serverGeneration == 1) {
2425         xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
2426     }
2427     return TRUE;
2428 }
2429
2430 static Bool
2431 NVSaveScreen(ScreenPtr pScreen, int mode)
2432 {
2433     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2434     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2435     NVPtr pNv = NVPTR(pScrn);
2436     int i;
2437     Bool on = xf86IsUnblank(mode);
2438     
2439     if (pNv->randr12_enable) {
2440         if (pScrn->vtSema) {
2441             for (i = 0; i < xf86_config->num_crtc; i++) {
2442                 
2443                 if (xf86_config->crtc[i]->enabled) {
2444                     NVCrtcBlankScreen(xf86_config->crtc[i],
2445                                       on);
2446                 }
2447             }
2448             
2449         }
2450         return TRUE;
2451     } else
2452         return vgaHWSaveScreen(pScreen, mode);
2453 }
2454
2455 static void
2456 NVSave(ScrnInfoPtr pScrn)
2457 {
2458     NVPtr pNv = NVPTR(pScrn);
2459     NVRegPtr nvReg = &pNv->SavedReg;
2460     vgaHWPtr pVga = VGAHWPTR(pScrn);
2461     vgaRegPtr vgaReg = &pVga->SavedReg;
2462     int i;
2463
2464     if (pNv->randr12_enable) {
2465         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2466         int vgaflags = VGA_SR_CMAP | VGA_SR_MODE;
2467         
2468         for (i = 0; i < xf86_config->num_crtc; i++) {
2469                 xf86_config->crtc[i]->funcs->save(xf86_config->crtc[i]);
2470         }
2471
2472         for (i = 0; i < xf86_config->num_output; i++) {
2473                 xf86_config->output[i]->funcs->save(xf86_config->
2474                                                     output[i]);
2475         }
2476
2477         vgaHWUnlock(pVga);
2478 #ifndef __powerpc__
2479         vgaflags |= VGA_SR_FONTS;
2480 #endif
2481         vgaHWSave(pScrn, vgaReg, vgaflags);
2482     } else {
2483         NVLockUnlock(pNv, 0);
2484         if(pNv->twoHeads) {
2485             nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->CRTCnumber * 0x3);
2486             NVLockUnlock(pNv, 0);
2487         }
2488         
2489         NVDACSave(pScrn, vgaReg, nvReg, pNv->Primary);
2490     }
2491 }
2492
2493 #ifdef RANDR
2494 static Bool
2495 NVRandRGetInfo(ScrnInfoPtr pScrn, Rotation *rotations)
2496 {
2497     NVPtr pNv = NVPTR(pScrn);
2498
2499     if(pNv->RandRRotation)
2500        *rotations = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_270;
2501     else
2502        *rotations = RR_Rotate_0;
2503
2504     return TRUE;
2505 }
2506
2507 static Bool
2508 NVRandRSetConfig(ScrnInfoPtr pScrn, xorgRRConfig *config)
2509 {
2510     NVPtr pNv = NVPTR(pScrn);
2511
2512     switch(config->rotation) {
2513         case RR_Rotate_0:
2514             pNv->Rotate = 0;
2515             pScrn->PointerMoved = pNv->PointerMoved;
2516             break;
2517
2518         case RR_Rotate_90:
2519             pNv->Rotate = -1;
2520             pScrn->PointerMoved = NVPointerMoved;
2521             break;
2522
2523         case RR_Rotate_270:
2524             pNv->Rotate = 1;
2525             pScrn->PointerMoved = NVPointerMoved;
2526             break;
2527
2528         default:
2529             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2530                     "Unexpected rotation in NVRandRSetConfig!\n");
2531             pNv->Rotate = 0;
2532             pScrn->PointerMoved = pNv->PointerMoved;
2533             return FALSE;
2534     }
2535
2536     return TRUE;
2537 }
2538
2539 static Bool
2540 NVDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer data)
2541 {
2542     switch(op) {
2543        case RR_GET_INFO:
2544           return NVRandRGetInfo(pScrn, (Rotation*)data);
2545        case RR_SET_CONFIG:
2546           return NVRandRSetConfig(pScrn, (xorgRRConfig*)data);
2547        default:
2548           return FALSE;
2549     }
2550
2551     return FALSE;
2552 }
2553 #endif