If you stare at nv_hw.c long enough, things start to make sense. I swear !
[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 #ifdef XF86DRI
35 #include "xf86drm.h"
36 #endif
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 Bool    NVEnterVTFBDev(int scrnIndex, int flags);
53 static void    NVLeaveVT(int scrnIndex, int flags);
54 static Bool    NVCloseScreen(int scrnIndex, ScreenPtr pScreen);
55 static Bool    NVSaveScreen(ScreenPtr pScreen, int mode);
56
57 /* Optional functions */
58 static void    NVFreeScreen(int scrnIndex, int flags);
59 static ModeStatus NVValidMode(int scrnIndex, DisplayModePtr mode,
60                               Bool verbose, int flags);
61 #ifdef RANDR
62 static Bool    NVDriverFunc(ScrnInfoPtr pScrnInfo, xorgDriverFuncOp op,
63                               pointer data);
64 #endif
65
66 /* Internally used functions */
67
68 static Bool     NVMapMem(ScrnInfoPtr pScrn);
69 static Bool     NVMapMemFBDev(ScrnInfoPtr pScrn);
70 static Bool     NVUnmapMem(ScrnInfoPtr pScrn);
71 static void     NVSave(ScrnInfoPtr pScrn);
72 static void     NVRestore(ScrnInfoPtr pScrn);
73 static Bool     NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
74
75
76 /*
77  * This contains the functions needed by the server after loading the
78  * driver module.  It must be supplied, and gets added the driver list by
79  * the Module Setup funtion in the dynamic case.  In the static case a
80  * reference to this is compiled in, and this requires that the name of
81  * this DriverRec be an upper-case version of the driver name.
82  */
83
84 _X_EXPORT DriverRec NV = {
85         NV_VERSION,
86         NV_DRIVER_NAME,
87         NVIdentify,
88         NVProbe,
89         NVAvailableOptions,
90         NULL,
91         0
92 };
93
94 /* Known cards as of 2006/06/16 */
95
96 static SymTabRec NVKnownChipsets[] =
97 {
98   { 0x12D20018, "RIVA 128" },
99
100   { 0x10DE0020, "RIVA TNT" },
101
102   { 0x10DE0028, "RIVA TNT2" },
103   { 0x10DE002A, "Unknown TNT2" },
104   { 0x10DE002C, "Vanta" },
105   { 0x10DE0029, "RIVA TNT2 Ultra" },
106   { 0x10DE002D, "RIVA TNT2 Model 64" },
107
108   { 0x10DE00A0, "Aladdin TNT2" },
109
110   { 0x10DE0100, "GeForce 256" },
111   { 0x10DE0101, "GeForce DDR" },
112   { 0x10DE0103, "Quadro" },
113
114   { 0x10DE0110, "GeForce2 MX/MX 400" },
115   { 0x10DE0111, "GeForce2 MX 100/200" },
116   { 0x10DE0112, "GeForce2 Go" },
117   { 0x10DE0113, "Quadro2 MXR/EX/Go" },
118
119   { 0x10DE01A0, "GeForce2 Integrated GPU" },
120
121   { 0x10DE0150, "GeForce2 GTS" },
122   { 0x10DE0151, "GeForce2 Ti" },
123   { 0x10DE0152, "GeForce2 Ultra" },
124   { 0x10DE0153, "Quadro2 Pro" },
125
126   { 0x10DE0170, "GeForce4 MX 460" },
127   { 0x10DE0171, "GeForce4 MX 440" },
128   { 0x10DE0172, "GeForce4 MX 420" },
129   { 0x10DE0173, "GeForce4 MX 440-SE" },
130   { 0x10DE0174, "GeForce4 440 Go" },
131   { 0x10DE0175, "GeForce4 420 Go" },
132   { 0x10DE0176, "GeForce4 420 Go 32M" },
133   { 0x10DE0177, "GeForce4 460 Go" },
134   { 0x10DE0178, "Quadro4 550 XGL" },
135 #if defined(__powerpc__)
136   { 0x10DE0179, "GeForce4 MX (Mac)" },
137 #else
138   { 0x10DE0179, "GeForce4 440 Go 64M" },
139 #endif
140   { 0x10DE017A, "Quadro NVS" },
141   { 0x10DE017C, "Quadro4 500 GoGL" },
142   { 0x10DE017D, "GeForce4 410 Go 16M" },
143
144   { 0x10DE0181, "GeForce4 MX 440 with AGP8X" },
145   { 0x10DE0182, "GeForce4 MX 440SE with AGP8X" },
146   { 0x10DE0183, "GeForce4 MX 420 with AGP8X" },
147   { 0x10DE0185, "GeForce4 MX 4000" },
148   { 0x10DE0186, "GeForce4 448 Go" },
149   { 0x10DE0187, "GeForce4 488 Go" },
150   { 0x10DE0188, "Quadro4 580 XGL" },
151 #if defined(__powerpc__)
152   { 0x10DE0189, "GeForce4 MX with AGP8X (Mac)" },
153 #endif
154   { 0x10DE018A, "Quadro4 NVS 280 SD" },
155   { 0x10DE018B, "Quadro4 380 XGL" },
156   { 0x10DE018C, "Quadro NVS 50 PCI" },
157   { 0x10DE018D, "GeForce4 448 Go" },
158
159   { 0x10DE01F0, "GeForce4 MX Integrated GPU" },
160
161   { 0x10DE0200, "GeForce3" },
162   { 0x10DE0201, "GeForce3 Ti 200" },
163   { 0x10DE0202, "GeForce3 Ti 500" },
164   { 0x10DE0203, "Quadro DCC" },
165
166   { 0x10DE0250, "GeForce4 Ti 4600" },
167   { 0x10DE0251, "GeForce4 Ti 4400" },
168   { 0x10DE0253, "GeForce4 Ti 4200" },
169   { 0x10DE0258, "Quadro4 900 XGL" },
170   { 0x10DE0259, "Quadro4 750 XGL" },
171   { 0x10DE025B, "Quadro4 700 XGL" },
172
173   { 0x10DE0280, "GeForce4 Ti 4800" },
174   { 0x10DE0281, "GeForce4 Ti 4200 with AGP8X" },
175   { 0x10DE0282, "GeForce4 Ti 4800 SE" },
176   { 0x10DE0286, "GeForce4 4200 Go" },
177   { 0x10DE028C, "Quadro4 700 GoGL" },
178   { 0x10DE0288, "Quadro4 980 XGL" },
179   { 0x10DE0289, "Quadro4 780 XGL" },
180
181   { 0x10DE0301, "GeForce FX 5800 Ultra" },
182   { 0x10DE0302, "GeForce FX 5800" },
183   { 0x10DE0308, "Quadro FX 2000" },
184   { 0x10DE0309, "Quadro FX 1000" },
185
186   { 0x10DE0311, "GeForce FX 5600 Ultra" },
187   { 0x10DE0312, "GeForce FX 5600" },
188   { 0x10DE0314, "GeForce FX 5600XT" },
189   { 0x10DE031A, "GeForce FX Go5600" },
190   { 0x10DE031B, "GeForce FX Go5650" },
191   { 0x10DE031C, "Quadro FX Go700" },
192
193   { 0x10DE0320, "GeForce FX 5200" },
194   { 0x10DE0321, "GeForce FX 5200 Ultra" },
195   { 0x10DE0322, "GeForce FX 5200" },
196   { 0x10DE0323, "GeForce FX 5200LE" },
197   { 0x10DE0324, "GeForce FX Go5200" },
198   { 0x10DE0325, "GeForce FX Go5250" },
199   { 0x10DE0326, "GeForce FX 5500" },
200   { 0x10DE0327, "GeForce FX 5100" },
201   { 0x10DE0328, "GeForce FX Go5200 32M/64M" },
202 #if defined(__powerpc__)
203   { 0x10DE0329, "GeForce FX 5200 (Mac)" },
204 #endif
205   { 0x10DE032A, "Quadro NVS 55/280 PCI" },
206   { 0x10DE032B, "Quadro FX 500/600 PCI" },
207   { 0x10DE032C, "GeForce FX Go53xx Series" },
208   { 0x10DE032D, "GeForce FX Go5100" },
209
210   { 0x10DE0330, "GeForce FX 5900 Ultra" },
211   { 0x10DE0331, "GeForce FX 5900" },
212   { 0x10DE0332, "GeForce FX 5900XT" },
213   { 0x10DE0333, "GeForce FX 5950 Ultra" },
214   { 0x10DE0334, "GeForce FX 5900ZT" },
215   { 0x10DE0338, "Quadro FX 3000" },
216   { 0x10DE033F, "Quadro FX 700" },
217
218   { 0x10DE0341, "GeForce FX 5700 Ultra" },
219   { 0x10DE0342, "GeForce FX 5700" },
220   { 0x10DE0343, "GeForce FX 5700LE" },
221   { 0x10DE0344, "GeForce FX 5700VE" },
222   { 0x10DE0347, "GeForce FX Go5700" },
223   { 0x10DE0348, "GeForce FX Go5700" },
224   { 0x10DE034C, "Quadro FX Go1000" },
225   { 0x10DE034E, "Quadro FX 1100" },
226
227   { 0x10DE0040, "GeForce 6800 Ultra" },
228   { 0x10DE0041, "GeForce 6800" },
229   { 0x10DE0042, "GeForce 6800 LE" },
230   { 0x10DE0043, "GeForce 6800 XE" },
231   { 0x10DE0044, "GeForce 6800 XT" },
232   { 0x10DE0045, "GeForce 6800 GT" },
233   { 0x10DE0046, "GeForce 6800 GT" },
234   { 0x10DE0047, "GeForce 6800 GS" },
235   { 0x10DE0048, "GeForce 6800 XT" },
236   { 0x10DE004E, "Quadro FX 4000" },
237
238   { 0x10DE00C0, "GeForce 6800 GS" },
239   { 0x10DE00C1, "GeForce 6800" },
240   { 0x10DE00C2, "GeForce 6800 LE" },
241   { 0x10DE00C3, "GeForce 6800 XT" },
242   { 0x10DE00C8, "GeForce Go 6800" },
243   { 0x10DE00C9, "GeForce Go 6800 Ultra" },
244   { 0x10DE00CC, "Quadro FX Go1400" },
245   { 0x10DE00CD, "Quadro FX 3450/4000 SDI" },
246   { 0x10DE00CE, "Quadro FX 1400" },
247
248   { 0x10DE0140, "GeForce 6600 GT" },
249   { 0x10DE0141, "GeForce 6600" },
250   { 0x10DE0142, "GeForce 6600 LE" },
251   { 0x10DE0143, "GeForce 6600 VE" },
252   { 0x10DE0144, "GeForce Go 6600" },
253   { 0x10DE0145, "GeForce 6610 XL" },
254   { 0x10DE0146, "GeForce Go 6600 TE/6200 TE" },
255   { 0x10DE0147, "GeForce 6700 XL" },
256   { 0x10DE0148, "GeForce Go 6600" },
257   { 0x10DE0149, "GeForce Go 6600 GT" },
258   { 0x10DE014C, "Quadro FX 550" },
259   { 0x10DE014D, "Quadro FX 550" },
260   { 0x10DE014E, "Quadro FX 540" },
261   { 0x10DE014F, "GeForce 6200" },
262
263   { 0x10DE0160, "GeForce 6500" },
264   { 0x10DE0161, "GeForce 6200 TurboCache(TM)" },
265   { 0x10DE0162, "GeForce 6200SE TurboCache(TM)" },
266   { 0x10DE0163, "GeForce 6200 LE" },
267   { 0x10DE0164, "GeForce Go 6200" },
268   { 0x10DE0165, "Quadro NVS 285" },
269   { 0x10DE0166, "GeForce Go 6400" },
270   { 0x10DE0167, "GeForce Go 6200" },
271   { 0x10DE0168, "GeForce Go 6400" },
272   { 0x10DE0169, "GeForce 6250" },
273
274   { 0x10DE0211, "GeForce 6800" },
275   { 0x10DE0212, "GeForce 6800 LE" },
276   { 0x10DE0215, "GeForce 6800 GT" },
277   { 0x10DE0218, "GeForce 6800 XT" },
278
279   { 0x10DE0221, "GeForce 6200" },
280   { 0x10DE0222, "GeForce 6200 A-LE" },
281
282   { 0x10DE0090, "GeForce 7800 GTX" },
283   { 0x10DE0091, "GeForce 7800 GTX" },
284   { 0x10DE0092, "GeForce 7800 GT" },
285   { 0x10DE0093, "GeForce 7800 GS" },
286   { 0x10DE0095, "GeForce 7800 SLI" },
287   { 0x10DE0098, "GeForce Go 7800" },
288   { 0x10DE0099, "GeForce Go 7800 GTX" },
289   { 0x10DE009D, "Quadro FX 4500" },
290
291   { 0x10DE01D1, "GeForce 7300 LE" },
292   { 0x10DE01D3, "GeForce 7300 SE" },
293   { 0x10DE01D6, "GeForce Go 7200" },
294   { 0x10DE01D7, "GeForce Go 7300" },
295   { 0x10DE01D8, "GeForce Go 7400" },
296   { 0x10DE01D9, "GeForce Go 7400 GS" },
297   { 0x10DE01DA, "Quadro NVS 110M" },
298   { 0x10DE01DB, "Quadro NVS 120M" },
299   { 0x10DE01DC, "Quadro FX 350M" },
300   { 0x10DE01DD, "GeForce 7500 LE" },
301   { 0x10DE01DE, "Quadro FX 350" },
302   { 0x10DE01DF, "GeForce 7300 GS" },
303
304   { 0x10DE0391, "GeForce 7600 GT" },
305   { 0x10DE0392, "GeForce 7600 GS" },
306   { 0x10DE0393, "GeForce 7300 GT" },
307   { 0x10DE0394, "GeForce 7600 LE" },
308   { 0x10DE0395, "GeForce 7300 GT" },
309   { 0x10DE0397, "GeForce Go 7700" },
310   { 0x10DE0398, "GeForce Go 7600" },
311   { 0x10DE0399, "GeForce Go 7600 GT"},
312   { 0x10DE039A, "Quadro NVS 300M" },
313   { 0x10DE039B, "GeForce Go 7900 SE" },
314   { 0x10DE039C, "Quadro FX 550M" },
315   { 0x10DE039E, "Quadro FX 560" },
316
317   { 0x10DE0290, "GeForce 7900 GTX" },
318   { 0x10DE0291, "GeForce 7900 GT" },
319   { 0x10DE0292, "GeForce 7900 GS" },
320   { 0x10DE0298, "GeForce Go 7900 GS" },
321   { 0x10DE0299, "GeForce Go 7900 GTX" },
322   { 0x10DE029A, "Quadro FX 2500M" },
323   { 0x10DE029B, "Quadro FX 1500M" },
324   { 0x10DE029C, "Quadro FX 5500" },
325   { 0x10DE029D, "Quadro FX 3500" },
326   { 0x10DE029E, "Quadro FX 1500" },
327   { 0x10DE029F, "Quadro FX 4500 X2" },
328
329   { 0x10DE0240, "GeForce 6150" },
330   { 0x10DE0241, "GeForce 6150 LE" },
331   { 0x10DE0242, "GeForce 6100" },
332   { 0x10DE0244, "GeForce Go 6150" },
333   { 0x10DE0247, "GeForce Go 6100" },
334
335   {-1, NULL}
336 };
337
338
339 /*
340  * List of symbols from other modules that this module references.  This
341  * list is used to tell the loader that it is OK for symbols here to be
342  * unresolved providing that it hasn't been told that they haven't been
343  * told that they are essential via a call to xf86LoaderReqSymbols() or
344  * xf86LoaderReqSymLists().  The purpose is this is to avoid warnings about
345  * unresolved symbols that are not required.
346  */
347
348 static const char *vgahwSymbols[] = {
349     "vgaHWUnmapMem",
350     "vgaHWDPMSSet",
351     "vgaHWFreeHWRec",
352     "vgaHWGetHWRec",
353     "vgaHWGetIndex",
354     "vgaHWInit",
355     "vgaHWMapMem",
356     "vgaHWProtect",
357     "vgaHWRestore",
358     "vgaHWSave",
359     "vgaHWSaveScreen",
360     NULL
361 };
362
363 static const char *fbSymbols[] = {
364     "fbPictureInit",
365     "fbScreenInit",
366     NULL
367 };
368
369 static const char *xaaSymbols[] = {
370     "XAACopyROP",
371     "XAACreateInfoRec",
372     "XAADestroyInfoRec",
373     "XAAFallbackOps",
374     "XAAInit",
375     "XAAPatternROP",
376     NULL
377 };
378
379 static const char *exaSymbols[] = {
380     "exaDriverInit",
381     "exaOffscreenInit",
382     NULL
383 };
384
385 static const char *ramdacSymbols[] = {
386     "xf86CreateCursorInfoRec",
387     "xf86DestroyCursorInfoRec",
388     "xf86InitCursor",
389     NULL
390 };
391
392 static const char *ddcSymbols[] = {
393     "xf86PrintEDID",
394     "xf86DoEDID_DDC2",
395     "xf86SetDDCproperties",
396     NULL
397 };
398
399 static const char *vbeSymbols[] = {
400     "VBEInit",
401     "vbeFree",
402     "vbeDoEDID",
403     NULL
404 };
405
406 static const char *i2cSymbols[] = {
407     "xf86CreateI2CBusRec",
408     "xf86I2CBusInit",
409     NULL
410 };
411
412 static const char *shadowSymbols[] = {
413     "ShadowFBInit",
414     NULL
415 };
416
417 static const char *fbdevHWSymbols[] = {
418     "fbdevHWInit",
419     "fbdevHWUseBuildinMode",
420
421     "fbdevHWGetVidmem",
422
423     /* colormap */
424     "fbdevHWLoadPaletteWeak",
425
426     /* ScrnInfo hooks */
427     "fbdevHWAdjustFrameWeak",
428     "fbdevHWEnterVT",
429     "fbdevHWLeaveVTWeak",
430     "fbdevHWModeInit",
431     "fbdevHWSave",
432     "fbdevHWSwitchModeWeak",
433     "fbdevHWValidModeWeak",
434
435     "fbdevHWMapMMIO",
436     "fbdevHWMapVidmem",
437
438     NULL
439 };
440
441 static const char *int10Symbols[] = {
442     "xf86FreeInt10",
443     "xf86InitInt10",
444     NULL
445 };
446
447 static const char *rivaSymbols[] = {
448    "RivaGetScrnInfoRec",
449    "RivaAvailableOptions",
450     NULL
451 };
452
453 #ifdef XF86DRI
454 const char *drmSymbols[] = {
455     "drmOpen", 
456     "drmAddBufs",
457     "drmAddMap",
458     "drmAgpAcquire",
459     "drmAgpVersionMajor",
460     "drmAgpVersionMinor",
461     "drmAgpAlloc",
462     "drmAgpBind",
463     "drmAgpEnable",
464     "drmAgpFree",
465     "drmAgpRelease",
466     "drmAgpUnbind",
467     "drmAuthMagic",
468     "drmCommandNone",
469     "drmCommandWrite",
470     "drmCreateContext",
471     "drmCtlInstHandler",
472     "drmCtlUninstHandler",
473     "drmDestroyContext",
474     "drmFreeVersion",
475     "drmGetInterruptFromBusID",
476     "drmGetLibVersion",
477     "drmGetVersion",
478     NULL
479 };
480
481 const char *driSymbols[] = {
482     "DRICloseScreen",
483     "DRICreateInfoRec",
484     "DRIDestroyInfoRec",
485     "DRIFinishScreenInit",
486     "DRIGetSAREAPrivate",
487     "DRILock",
488     "DRIQueryVersion",
489     "DRIScreenInit",
490     "DRIUnlock",
491     "GlxSetVisualConfigs",
492     "DRICreatePCIBusID",
493     NULL
494 };
495
496 #endif
497
498 static MODULESETUPPROTO(nvSetup);
499
500 static XF86ModuleVersionInfo nvVersRec =
501 {
502     "nv",
503     MODULEVENDORSTRING,
504     MODINFOSTRING1,
505     MODINFOSTRING2,
506     XORG_VERSION_CURRENT,
507     NV_MAJOR_VERSION, NV_MINOR_VERSION, NV_PATCHLEVEL,
508     ABI_CLASS_VIDEODRV,                     /* This is a video driver */
509     ABI_VIDEODRV_VERSION,
510     MOD_CLASS_VIDEODRV,
511     {0,0,0,0}
512 };
513
514 _X_EXPORT XF86ModuleData nvModuleData = { &nvVersRec, nvSetup, NULL };
515
516
517 typedef enum {
518     OPTION_SW_CURSOR,
519     OPTION_HW_CURSOR,
520     OPTION_NOACCEL,
521     OPTION_SHADOW_FB,
522     OPTION_FBDEV,
523     OPTION_ROTATE,
524     OPTION_VIDEO_KEY,
525     OPTION_FLAT_PANEL,
526     OPTION_FP_DITHER,
527     OPTION_CRTC_NUMBER,
528     OPTION_FP_SCALE,
529     OPTION_FP_TWEAK,
530     OPTION_ACCELMETHOD
531 } NVOpts;
532
533
534 static const OptionInfoRec NVOptions[] = {
535     { OPTION_SW_CURSOR,         "SWcursor",     OPTV_BOOLEAN,   {0}, FALSE },
536     { OPTION_HW_CURSOR,         "HWcursor",     OPTV_BOOLEAN,   {0}, FALSE },
537     { OPTION_NOACCEL,           "NoAccel",      OPTV_BOOLEAN,   {0}, FALSE },
538     { OPTION_SHADOW_FB,         "ShadowFB",     OPTV_BOOLEAN,   {0}, FALSE },
539     { OPTION_FBDEV,             "UseFBDev",     OPTV_BOOLEAN,   {0}, FALSE },
540     { OPTION_ROTATE,            "Rotate",       OPTV_ANYSTR,    {0}, FALSE },
541     { OPTION_VIDEO_KEY,         "VideoKey",     OPTV_INTEGER,   {0}, FALSE },
542     { OPTION_FLAT_PANEL,        "FlatPanel",    OPTV_BOOLEAN,   {0}, FALSE },
543     { OPTION_FP_DITHER,         "FPDither",     OPTV_BOOLEAN,   {0}, FALSE },
544     { OPTION_CRTC_NUMBER,       "CrtcNumber",   OPTV_INTEGER,   {0}, FALSE },
545     { OPTION_FP_SCALE,          "FPScale",      OPTV_BOOLEAN,   {0}, FALSE },
546     { OPTION_FP_TWEAK,          "FPTweak",      OPTV_INTEGER,   {0}, FALSE },
547     { OPTION_ACCELMETHOD,        "AccelMethod", OPTV_STRING,    {0}, FALSE },
548     { -1,                       NULL,           OPTV_NONE,      {0}, FALSE }
549 };
550
551 /*
552  * This is intentionally screen-independent.  It indicates the binding
553  * choice made in the first PreInit.
554  */
555 static int pix24bpp = 0;
556
557
558 static Bool
559 NVGetRec(ScrnInfoPtr pScrn)
560 {
561     /*
562      * Allocate an NVRec, and hook it into pScrn->driverPrivate.
563      * pScrn->driverPrivate is initialised to NULL, so we can check if
564      * the allocation has already been done.
565      */
566     if (pScrn->driverPrivate != NULL)
567         return TRUE;
568
569     pScrn->driverPrivate = xnfcalloc(sizeof(NVRec), 1);
570     /* Initialise it */
571
572     return TRUE;
573 }
574
575 static void
576 NVFreeRec(ScrnInfoPtr pScrn)
577 {
578     if (pScrn->driverPrivate == NULL)
579         return;
580     xfree(pScrn->driverPrivate);
581     pScrn->driverPrivate = NULL;
582 }
583
584
585 static pointer
586 nvSetup(pointer module, pointer opts, int *errmaj, int *errmin)
587 {
588     static Bool setupDone = FALSE;
589
590     /* This module should be loaded only once, but check to be sure. */
591
592     if (!setupDone) {
593         setupDone = TRUE;
594         xf86AddDriver(&NV, module, 0);
595
596         /*
597          * Modules that this driver always requires may be loaded here
598          * by calling LoadSubModule().
599          */
600         /*
601          * Tell the loader about symbols from other modules that this module
602          * might refer to.
603          */
604         LoaderRefSymLists(vgahwSymbols, xaaSymbols, exaSymbols, fbSymbols,
605 #ifdef XF86DRI
606                           drmSymbols, 
607 #endif
608                           ramdacSymbols, shadowSymbols, rivaSymbols,
609                           i2cSymbols, ddcSymbols, vbeSymbols,
610                           fbdevHWSymbols, int10Symbols, NULL);
611
612         /*
613          * The return value must be non-NULL on success even though there
614          * is no TearDownProc.
615          */
616         return (pointer)1;
617     } else {
618         if (errmaj) *errmaj = LDR_ONCEONLY;
619         return NULL;
620     }
621 }
622
623 static const OptionInfoRec *
624 NVAvailableOptions(int chipid, int busid)
625 {
626     if(chipid == 0x12D20018) {
627         if (!xf86LoadOneModule("riva128", NULL)) {
628             return NULL;
629         } else
630             return RivaAvailableOptions(chipid, busid);
631     }
632     
633     return NVOptions;
634 }
635
636 /* Mandatory */
637 static void
638 NVIdentify(int flags)
639 {
640     xf86PrintChipsets(NV_NAME, "driver for NVIDIA chipsets", NVKnownChipsets);
641 }
642
643
644 static Bool
645 NVGetScrnInfoRec(PciChipsets *chips, int chip)
646 {
647     ScrnInfoPtr pScrn;
648
649     pScrn = xf86ConfigPciEntity(NULL, 0, chip,
650                                 chips, NULL, NULL, NULL,
651                                 NULL, NULL);
652
653     if(!pScrn) return FALSE;
654
655     pScrn->driverVersion    = NV_VERSION;
656     pScrn->driverName       = NV_DRIVER_NAME;
657     pScrn->name             = NV_NAME;
658
659     pScrn->Probe            = NVProbe;
660     pScrn->PreInit          = NVPreInit;
661     pScrn->ScreenInit       = NVScreenInit;
662     pScrn->SwitchMode       = NVSwitchMode;
663     pScrn->AdjustFrame      = NVAdjustFrame;
664     pScrn->EnterVT          = NVEnterVT;
665     pScrn->LeaveVT          = NVLeaveVT;
666     pScrn->FreeScreen       = NVFreeScreen;
667     pScrn->ValidMode        = NVValidMode;
668
669     return TRUE;
670 }
671
672 #define MAX_CHIPS MAXSCREENS
673
674
675 static CARD32 
676 NVGetPCIXpressChip (pciVideoPtr pVideo)
677 {
678     volatile CARD32 *regs;
679     CARD32 pciid, pcicmd;
680     PCITAG Tag = ((pciConfigPtr)(pVideo->thisCard))->tag;
681
682     pcicmd = pciReadLong(Tag, PCI_CMD_STAT_REG);
683     pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd | PCI_CMD_MEM_ENABLE);
684     
685     regs = xf86MapPciMem(-1, VIDMEM_MMIO, Tag, pVideo->memBase[0], 0x2000);
686
687     pciid = regs[0x1800/4];
688
689     xf86UnMapVidMem(-1, (pointer)regs, 0x2000);
690
691     pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd);
692
693     if((pciid & 0x0000ffff) == 0x000010DE) 
694        pciid = 0x10DE0000 | (pciid >> 16);
695     else 
696     if((pciid & 0xffff0000) == 0xDE100000) /* wrong endian */
697        pciid = 0x10DE0000 | ((pciid << 8) & 0x0000ff00) |
698                             ((pciid >> 8) & 0x000000ff);
699
700     return pciid;
701 }
702
703
704 /* Mandatory */
705 static Bool
706 NVProbe(DriverPtr drv, int flags)
707 {
708     int i;
709     GDevPtr *devSections;
710     int *usedChips;
711     SymTabRec NVChipsets[MAX_CHIPS + 1];
712     PciChipsets NVPciChipsets[MAX_CHIPS + 1];
713     pciVideoPtr *ppPci;
714     int numDevSections;
715     int numUsed;
716     Bool foundScreen = FALSE;
717
718
719     if ((numDevSections = xf86MatchDevice(NV_DRIVER_NAME, &devSections)) <= 0) 
720         return FALSE;  /* no matching device section */
721
722     if (!(ppPci = xf86GetPciVideoInfo())) 
723         return FALSE;  /* no PCI cards found */
724
725     numUsed = 0;
726
727     /* Create the NVChipsets and NVPciChipsets from found devices */
728     while (*ppPci && (numUsed < MAX_CHIPS)) {
729         if(((*ppPci)->vendor == PCI_VENDOR_NVIDIA_SGS) || 
730            ((*ppPci)->vendor == PCI_VENDOR_NVIDIA)) 
731         {
732             SymTabRec *nvchips = NVKnownChipsets;
733             int pciid = ((*ppPci)->vendor << 16) | (*ppPci)->chipType;
734             int token = pciid;
735
736             if(((token & 0xfff0) == CHIPSET_PCIE) ||
737                ((token & 0xfff0) == 0x02E0))
738             {
739                 token = NVGetPCIXpressChip(*ppPci);
740             }
741
742             while(nvchips->name) {
743                if(token == nvchips->token)
744                   break;
745                nvchips++;
746             }
747
748             if(nvchips->name) { /* found one */
749                NVChipsets[numUsed].token = pciid;
750                NVChipsets[numUsed].name = nvchips->name;
751                NVPciChipsets[numUsed].numChipset = pciid; 
752                NVPciChipsets[numUsed].PCIid = pciid;
753                NVPciChipsets[numUsed].resList = RES_SHARED_VGA;
754                numUsed++;
755             } else if ((*ppPci)->vendor == PCI_VENDOR_NVIDIA) {
756                /* look for a compatible devices which may be newer than 
757                   the NVKnownChipsets list above.  */
758                switch(token & 0xfff0) {
759                case CHIPSET_NV17:
760                case CHIPSET_NV18:
761                case CHIPSET_NV25:
762                case CHIPSET_NV28:
763                case CHIPSET_NV30:
764                case CHIPSET_NV31:
765                case CHIPSET_NV34:
766                case CHIPSET_NV35:
767                case CHIPSET_NV36:
768                case CHIPSET_NV40:
769                case CHIPSET_NV41:
770                case 0x0120:
771                case CHIPSET_NV43:
772                case CHIPSET_NV44:
773                case 0x0130:
774                case CHIPSET_G72:
775                case CHIPSET_G70:
776                case CHIPSET_NV45:
777                case CHIPSET_NV44A:
778                case 0x0230:
779                case CHIPSET_G71:
780                case CHIPSET_G73:
781                case CHIPSET_C512:
782                    NVChipsets[numUsed].token = pciid;
783                    NVChipsets[numUsed].name = "Unknown NVIDIA chip";
784                    NVPciChipsets[numUsed].numChipset = pciid;
785                    NVPciChipsets[numUsed].PCIid = pciid;
786                    NVPciChipsets[numUsed].resList = RES_SHARED_VGA;
787                    numUsed++;
788                    break;
789                default:  break;  /* we don't recognize it */
790                }
791             }
792         }
793         ppPci++;
794     }
795
796     /* terminate the list */
797     NVChipsets[numUsed].token = -1;
798     NVChipsets[numUsed].name = NULL; 
799     NVPciChipsets[numUsed].numChipset = -1;
800     NVPciChipsets[numUsed].PCIid = -1;
801     NVPciChipsets[numUsed].resList = RES_UNDEFINED;
802
803     numUsed = xf86MatchPciInstances(NV_NAME, 0, NVChipsets, NVPciChipsets,
804                                     devSections, numDevSections, drv,
805                                     &usedChips);
806                         
807     if (numUsed <= 0) 
808         return FALSE;
809
810     if (flags & PROBE_DETECT)
811         foundScreen = TRUE;
812     else for (i = 0; i < numUsed; i++) {
813         pciVideoPtr pPci;
814
815         pPci = xf86GetPciInfoForEntity(usedChips[i]);
816         if(pPci->vendor == PCI_VENDOR_NVIDIA_SGS) {
817             if (!xf86LoadDrvSubModule(drv, "riva128")) {
818                   continue;
819             }
820             xf86LoaderReqSymLists(rivaSymbols, NULL);
821             if(RivaGetScrnInfoRec(NVPciChipsets, usedChips[i]))
822                 foundScreen = TRUE;
823         } else {
824             if(NVGetScrnInfoRec(NVPciChipsets, usedChips[i])) 
825                 foundScreen = TRUE;
826         }    
827     }
828
829     xfree(devSections);
830     xfree(usedChips);
831
832     return foundScreen;
833 }
834
835 /* Usually mandatory */
836 Bool
837 NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
838 {
839     return NVModeInit(xf86Screens[scrnIndex], mode);
840 }
841
842 /*
843  * This function is used to initialize the Start Address - the first
844  * displayed location in the video memory.
845  */
846 /* Usually mandatory */
847 void 
848 NVAdjustFrame(int scrnIndex, int x, int y, int flags)
849 {
850     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
851     int startAddr;
852     NVPtr pNv = NVPTR(pScrn);
853     NVFBLayout *pLayout = &pNv->CurrentLayout;
854
855     startAddr = (((y*pLayout->displayWidth)+x)*(pLayout->bitsPerPixel/8));
856     NVSetStartAddress(pNv, startAddr);
857 }
858
859
860 /*
861  * This is called when VT switching back to the X server.  Its job is
862  * to reinitialise the video mode.
863  *
864  * We may wish to unmap video/MMIO memory too.
865  */
866
867 /* Mandatory */
868 static Bool
869 NVEnterVT(int scrnIndex, int flags)
870 {
871     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
872     NVPtr pNv = NVPTR(pScrn);
873
874     if (!NVModeInit(pScrn, pScrn->currentMode))
875         return FALSE;
876     NVAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
877
878     if(pNv->overlayAdaptor)
879         NVResetVideo(pScrn);
880     return TRUE;
881 }
882
883 static Bool
884 NVEnterVTFBDev(int scrnIndex, int flags)
885 {
886     fbdevHWEnterVT(scrnIndex,flags);
887     return TRUE;
888 }
889
890 /*
891  * This is called when VT switching away from the X server.  Its job is
892  * to restore the previous (text) mode.
893  *
894  * We may wish to remap video/MMIO memory too.
895  */
896
897 /* Mandatory */
898 static void
899 NVLeaveVT(int scrnIndex, int flags)
900 {
901     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
902     NVPtr pNv = NVPTR(pScrn);
903
904     NVSync(pScrn);
905     NVRestore(pScrn);
906     NVLockUnlock(pNv, 1);
907 }
908
909
910
911 static void 
912 NVBlockHandler (
913     int i, 
914     pointer blockData, 
915     pointer pTimeout,
916     pointer pReadmask
917 )
918 {
919     ScreenPtr     pScreen = screenInfo.screens[i];
920     ScrnInfoPtr   pScrnInfo = xf86Screens[i];
921     NVPtr         pNv = NVPTR(pScrnInfo);
922
923     if (pNv->DMAKickoffCallback)
924         (*pNv->DMAKickoffCallback)(pNv);
925     
926     pScreen->BlockHandler = pNv->BlockHandler;
927     (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
928     pScreen->BlockHandler = NVBlockHandler;
929
930     if (pNv->VideoTimerCallback) 
931         (*pNv->VideoTimerCallback)(pScrnInfo, currentTime.milliseconds);
932
933 }
934
935
936 /*
937  * This is called at the end of each server generation.  It restores the
938  * original (text) mode.  It should also unmap the video memory, and free
939  * any per-generation data allocated by the driver.  It should finish
940  * by unwrapping and calling the saved CloseScreen function.
941  */
942
943 /* Mandatory */
944 static Bool
945 NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
946 {
947     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
948     NVPtr pNv = NVPTR(pScrn);
949
950     if (pScrn->vtSema) {
951         NVSync(pScrn);
952         NVRestore(pScrn);
953         NVLockUnlock(pNv, 1);
954     }
955
956     NVUnmapMem(pScrn);
957     vgaHWUnmapMem(pScrn);
958     if (pNv->AccelInfoRec)
959         XAADestroyInfoRec(pNv->AccelInfoRec);
960     if (pNv->CursorInfoRec)
961         xf86DestroyCursorInfoRec(pNv->CursorInfoRec);
962     if (pNv->ShadowPtr)
963         xfree(pNv->ShadowPtr);
964     if (pNv->DGAModes)
965         xfree(pNv->DGAModes);
966     if (pNv->overlayAdaptor)
967         xfree(pNv->overlayAdaptor);
968     if (pNv->blitAdaptor)
969         xfree(pNv->blitAdaptor);
970
971     pScrn->vtSema = FALSE;
972     pScreen->CloseScreen = pNv->CloseScreen;
973     pScreen->BlockHandler = pNv->BlockHandler;
974     return (*pScreen->CloseScreen)(scrnIndex, pScreen);
975 }
976
977 /* Free up any persistent data structures */
978
979 /* Optional */
980 static void
981 NVFreeScreen(int scrnIndex, int flags)
982 {
983     /*
984      * This only gets called when a screen is being deleted.  It does not
985      * get called routinely at the end of a server generation.
986      */
987     if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
988         vgaHWFreeHWRec(xf86Screens[scrnIndex]);
989     NVFreeRec(xf86Screens[scrnIndex]);
990 }
991
992
993 /* Checks if a mode is suitable for the selected chipset. */
994
995 /* Optional */
996 static ModeStatus
997 NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
998 {
999     NVPtr pNv = NVPTR(xf86Screens[scrnIndex]);
1000
1001     if(pNv->fpWidth && pNv->fpHeight)
1002       if((pNv->fpWidth < mode->HDisplay) || (pNv->fpHeight < mode->VDisplay))
1003         return (MODE_PANEL);
1004
1005     return (MODE_OK);
1006 }
1007
1008 static void
1009 nvProbeDDC(ScrnInfoPtr pScrn, int index)
1010 {
1011     vbeInfoPtr pVbe;
1012
1013     if (xf86LoadSubModule(pScrn, "vbe")) {
1014         pVbe = VBEInit(NULL,index);
1015         ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
1016         vbeFree(pVbe);
1017     }
1018 }
1019
1020
1021 Bool NVI2CInit(ScrnInfoPtr pScrn)
1022 {
1023     char *mod = "i2c";
1024
1025     if (xf86LoadSubModule(pScrn, mod)) {
1026         xf86LoaderReqSymLists(i2cSymbols,NULL);
1027
1028         mod = "ddc";
1029         if(xf86LoadSubModule(pScrn, mod)) {
1030             xf86LoaderReqSymLists(ddcSymbols, NULL);
1031             return NVDACi2cInit(pScrn);
1032         } 
1033     }
1034
1035     xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1036               "Couldn't load %s module.  DDC probing can't be done\n", mod);
1037
1038     return FALSE;
1039 }
1040
1041 /* Mandatory */
1042 Bool
1043 NVPreInit(ScrnInfoPtr pScrn, int flags)
1044 {
1045     NVPtr pNv;
1046     MessageType from;
1047     int i, max_width, max_height;
1048     ClockRangePtr clockRanges;
1049     const char *s;
1050
1051     if (flags & PROBE_DETECT) {
1052         EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
1053
1054         if (!pEnt)
1055             return FALSE;
1056
1057         i = pEnt->index;
1058         xfree(pEnt);
1059
1060         nvProbeDDC(pScrn, i);
1061         return TRUE;
1062     }
1063
1064     /*
1065      * Note: This function is only called once at server startup, and
1066      * not at the start of each server generation.  This means that
1067      * only things that are persistent across server generations can
1068      * be initialised here.  xf86Screens[] is (pScrn is a pointer to one
1069      * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()  
1070      * are too, and should be used for data that must persist across
1071      * server generations.
1072      *
1073      * Per-generation data should be allocated with
1074      * AllocateScreenPrivateIndex() from the ScreenInit() function.
1075      */
1076
1077     /* Check the number of entities, and fail if it isn't one. */
1078     if (pScrn->numEntities != 1)
1079         return FALSE;
1080
1081     /* Allocate the NVRec driverPrivate */
1082     if (!NVGetRec(pScrn)) {
1083         return FALSE;
1084     }
1085     pNv = NVPTR(pScrn);
1086
1087     /* Get the entity, and make sure it is PCI. */
1088     pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
1089     if (pNv->pEnt->location.type != BUS_PCI)
1090         return FALSE;
1091  
1092     /* Find the PCI info for this screen */
1093     pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index);
1094     pNv->PciTag = pciTag(pNv->PciInfo->bus, pNv->PciInfo->device,
1095                           pNv->PciInfo->func);
1096
1097     pNv->Primary = xf86IsPrimaryPci(pNv->PciInfo);
1098
1099     /* Initialize the card through int10 interface if needed */
1100     if (xf86LoadSubModule(pScrn, "int10")) {
1101         xf86LoaderReqSymLists(int10Symbols, NULL);
1102 #if !defined(__alpha__) && !defined(__powerpc__)
1103         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");
1104         pNv->pInt = xf86InitInt10(pNv->pEnt->index);
1105 #endif
1106     }
1107    
1108     xf86SetOperatingState(resVgaIo, pNv->pEnt->index, ResUnusedOpr);
1109     xf86SetOperatingState(resVgaMem, pNv->pEnt->index, ResDisableOpr);
1110
1111     /* Set pScrn->monitor */
1112     pScrn->monitor = pScrn->confScreen->monitor;
1113
1114     /*
1115      * Set the Chipset and ChipRev, allowing config file entries to
1116      * override.
1117      */
1118     if (pNv->pEnt->device->chipset && *pNv->pEnt->device->chipset) {
1119         pScrn->chipset = pNv->pEnt->device->chipset;
1120         pNv->Chipset = xf86StringToToken(NVKnownChipsets, pScrn->chipset);
1121         from = X_CONFIG;
1122     } else if (pNv->pEnt->device->chipID >= 0) {
1123         pNv->Chipset = pNv->pEnt->device->chipID;
1124         pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, 
1125                                                    pNv->Chipset);
1126         from = X_CONFIG;
1127         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
1128                    pNv->Chipset);
1129     } else {
1130         from = X_PROBED;
1131         pNv->Chipset = (pNv->PciInfo->vendor << 16) | pNv->PciInfo->chipType;
1132
1133         if(((pNv->Chipset & 0xfff0) == CHIPSET_PCIE) ||
1134            ((pNv->Chipset & 0xfff0) == 0x02E0))
1135         {
1136             pNv->Chipset = NVGetPCIXpressChip(pNv->PciInfo);
1137         }
1138
1139         pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, 
1140                                                    pNv->Chipset);
1141         if(!pScrn->chipset)
1142           pScrn->chipset = "Unknown NVIDIA chipset";
1143     }
1144
1145     if (pNv->pEnt->device->chipRev >= 0) {
1146         pNv->ChipRev = pNv->pEnt->device->chipRev;
1147         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
1148                    pNv->ChipRev);
1149     } else {
1150         pNv->ChipRev = pNv->PciInfo->chipRev;
1151     }
1152
1153     /*
1154      * This shouldn't happen because such problems should be caught in
1155      * NVProbe(), but check it just in case.
1156      */
1157     if (pScrn->chipset == NULL) {
1158         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1159                    "ChipID 0x%04X is not recognised\n", pNv->Chipset);
1160         xf86FreeInt10(pNv->pInt);
1161         return FALSE;
1162     }
1163     if (pNv->Chipset < 0) {
1164         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1165                    "Chipset \"%s\" is not recognised\n", pScrn->chipset);
1166         xf86FreeInt10(pNv->pInt);
1167         return FALSE;
1168     }
1169
1170     xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
1171
1172
1173     /*
1174      * The first thing we should figure out is the depth, bpp, etc.
1175      */
1176
1177     if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
1178         xf86FreeInt10(pNv->pInt);
1179         return FALSE;
1180     } else {
1181         /* Check that the returned depth is one we support */
1182         switch (pScrn->depth) {
1183             case 8:
1184             case 15:
1185             case 16:
1186             case 24:
1187                 /* OK */
1188                 break;
1189             default:
1190                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1191                     "Given depth (%d) is not supported by this driver\n",
1192                     pScrn->depth);
1193                 xf86FreeInt10(pNv->pInt);
1194                 return FALSE;
1195         }
1196     }
1197     xf86PrintDepthBpp(pScrn);
1198
1199     /* Get the depth24 pixmap format */
1200     if (pScrn->depth == 24 && pix24bpp == 0)
1201         pix24bpp = xf86GetBppFromDepth(pScrn, 24);
1202
1203     /*
1204      * This must happen after pScrn->display has been set because
1205      * xf86SetWeight references it.
1206      */
1207     if (pScrn->depth > 8) {
1208         /* The defaults are OK for us */
1209         rgb zeros = {0, 0, 0};
1210
1211         if (!xf86SetWeight(pScrn, zeros, zeros)) {
1212             xf86FreeInt10(pNv->pInt);
1213             return FALSE;
1214         }
1215     }
1216
1217     if (!xf86SetDefaultVisual(pScrn, -1)) {
1218         xf86FreeInt10(pNv->pInt);
1219         return FALSE;
1220     } else {
1221         /* We don't currently support DirectColor at > 8bpp */
1222         if (pScrn->depth > 8 && (pScrn->defaultVisual != TrueColor)) {
1223             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
1224                        " (%s) is not supported at depth %d\n",
1225                        xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
1226             xf86FreeInt10(pNv->pInt);
1227             return FALSE;
1228         }
1229     }
1230
1231     /* The vgahw module should be loaded here when needed */
1232     if (!xf86LoadSubModule(pScrn, "vgahw")) {
1233         xf86FreeInt10(pNv->pInt);
1234         return FALSE;
1235     }
1236     
1237     xf86LoaderReqSymLists(vgahwSymbols, NULL);
1238
1239     /*
1240      * Allocate a vgaHWRec
1241      */
1242     if (!vgaHWGetHWRec(pScrn)) {
1243         xf86FreeInt10(pNv->pInt);
1244         return FALSE;
1245     }
1246     
1247     /* We use a programmable clock */
1248     pScrn->progClock = TRUE;
1249
1250     /* Collect all of the relevant option flags (fill in pScrn->options) */
1251     xf86CollectOptions(pScrn, NULL);
1252
1253     /* Process the options */
1254     if (!(pNv->Options = xalloc(sizeof(NVOptions))))
1255         return FALSE;
1256     memcpy(pNv->Options, NVOptions, sizeof(NVOptions));
1257     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options);
1258
1259     /* Set the bits per RGB for 8bpp mode */
1260     if (pScrn->depth == 8)
1261         pScrn->rgbBits = 8;
1262
1263     from = X_DEFAULT;
1264     pNv->HWCursor = TRUE;
1265     /*
1266      * The preferred method is to use the "hw cursor" option as a tri-state
1267      * option, with the default set above.
1268      */
1269     if (xf86GetOptValBool(pNv->Options, OPTION_HW_CURSOR, &pNv->HWCursor)) {
1270         from = X_CONFIG;
1271     }
1272     /* For compatibility, accept this too (as an override) */
1273     if (xf86ReturnOptValBool(pNv->Options, OPTION_SW_CURSOR, FALSE)) {
1274         from = X_CONFIG;
1275         pNv->HWCursor = FALSE;
1276     }
1277     xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
1278                 pNv->HWCursor ? "HW" : "SW");
1279
1280     pNv->FpScale = TRUE;
1281     if (xf86GetOptValBool(pNv->Options, OPTION_FP_SCALE, &pNv->FpScale)) {
1282         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Flat panel scaling %s\n",
1283                    pNv->FpScale ? "on" : "off");
1284     }
1285     if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) {
1286         pNv->NoAccel = TRUE;
1287         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
1288     }
1289     if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) {
1290         pNv->ShadowFB = TRUE;
1291         pNv->NoAccel = TRUE;
1292         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1293                 "Using \"Shadow Framebuffer\" - acceleration disabled\n");
1294     }
1295     if (xf86ReturnOptValBool(pNv->Options, OPTION_FBDEV, FALSE)) {
1296         pNv->FBDev = TRUE;
1297         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1298                 "Using framebuffer device\n");
1299     }
1300     if (!pNv->NoAccel) {
1301         if((s = (char *)xf86GetOptValString(pNv->Options, OPTION_ACCELMETHOD))) {
1302             if(!xf86NameCmp(s,"XAA")) {
1303                 from = X_CONFIG;
1304                 pNv->useEXA = FALSE;
1305             } else if(!xf86NameCmp(s,"EXA")) {
1306                 from = X_CONFIG;
1307                 pNv->useEXA = TRUE;
1308             }
1309         }
1310         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using %s acceleration method\n", s);
1311     } else {
1312         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
1313     }
1314     
1315     if (pNv->FBDev) {
1316         /* check for linux framebuffer device */
1317         if (!xf86LoadSubModule(pScrn, "fbdevhw")) {
1318             xf86FreeInt10(pNv->pInt);
1319             return FALSE;
1320         }
1321         
1322         xf86LoaderReqSymLists(fbdevHWSymbols, NULL);
1323         if (!fbdevHWInit(pScrn, pNv->PciInfo, NULL)) {
1324             xf86FreeInt10(pNv->pInt);
1325             return FALSE;
1326         }
1327         pScrn->SwitchMode    = fbdevHWSwitchModeWeak();
1328         pScrn->AdjustFrame   = fbdevHWAdjustFrameWeak();
1329         pScrn->EnterVT       = NVEnterVTFBDev;
1330         pScrn->LeaveVT       = fbdevHWLeaveVTWeak();
1331         pScrn->ValidMode     = fbdevHWValidModeWeak();
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             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1419                 "MemBase 0x%08lX doesn't match any PCI base register.\n",
1420                 pNv->pEnt->device->MemBase);
1421             xf86FreeInt10(pNv->pInt);
1422             NVFreeRec(pScrn);
1423             return FALSE;
1424         }
1425         pNv->FbAddress = pNv->pEnt->device->MemBase;
1426         from = X_CONFIG;
1427     } else {
1428         if (pNv->PciInfo->memBase[1] != 0) {
1429             pNv->FbAddress = pNv->PciInfo->memBase[1] & 0xff800000;
1430             from = X_PROBED;
1431         } else {
1432             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1433                            "No valid FB address in PCI config space\n");
1434             xf86FreeInt10(pNv->pInt);
1435             NVFreeRec(pScrn);
1436             return FALSE;
1437         }
1438     }
1439     xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
1440                (unsigned long)pNv->FbAddress);
1441
1442     if (pNv->pEnt->device->IOBase != 0) {
1443         /* Require that the config file value matches one of the PCI values. */
1444         if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->IOBase)) {
1445             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1446                 "IOBase 0x%08lX doesn't match any PCI base register.\n",
1447                 pNv->pEnt->device->IOBase);
1448             xf86FreeInt10(pNv->pInt);
1449             NVFreeRec(pScrn);
1450             return FALSE;
1451         }
1452         pNv->IOAddress = pNv->pEnt->device->IOBase;
1453         from = X_CONFIG;
1454     } else {
1455         if (pNv->PciInfo->memBase[0] != 0) {
1456             pNv->IOAddress = pNv->PciInfo->memBase[0] & 0xffffc000;
1457             from = X_PROBED;
1458         } else {
1459             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1460                         "No valid MMIO address in PCI config space\n");
1461             xf86FreeInt10(pNv->pInt);
1462             NVFreeRec(pScrn);
1463             return FALSE;
1464         }
1465     }
1466     xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
1467                (unsigned long)pNv->IOAddress);
1468      
1469     if (xf86RegisterResources(pNv->pEnt->index, NULL, ResExclusive)) {
1470         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1471                 "xf86RegisterResources() found resource conflicts\n");
1472         xf86FreeInt10(pNv->pInt);
1473         NVFreeRec(pScrn);
1474         return FALSE;
1475     }
1476
1477     switch (pNv->Chipset & 0x0ff0) {
1478     case CHIPSET_NV10:   /* GeForce 256 */
1479     case CHIPSET_NV11:   /* GeForce2 MX */
1480     case CHIPSET_NV15:   /* GeForce2 */
1481     case CHIPSET_NV17:   /* GeForce4 MX */
1482     case CHIPSET_NV18:   /* GeForce4 MX (8x AGP) */
1483     case CHIPSET_NFORCE: /* nForce */
1484     case CHIPSET_NFORCE2:/* nForce2 */
1485          pNv->Architecture =  NV_ARCH_10;
1486          break;
1487     case CHIPSET_NV20:   /* GeForce3 */
1488     case CHIPSET_NV25:   /* GeForce4 Ti */
1489     case CHIPSET_NV28:   /* GeForce4 Ti (8x AGP) */
1490          pNv->Architecture =  NV_ARCH_20;
1491          break;
1492     case CHIPSET_NV30:   /* GeForceFX 5800 */
1493     case CHIPSET_NV31:   /* GeForceFX 5600 */
1494     case CHIPSET_NV34:   /* GeForceFX 5200 */
1495     case CHIPSET_NV35:   /* GeForceFX 5900 */
1496     case CHIPSET_NV36:   /* GeForceFX 5700 */
1497          pNv->Architecture =  NV_ARCH_30;
1498          break;
1499     case CHIPSET_NV40:   /* GeForce 6800 */
1500     case CHIPSET_NV41:   /* GeForce 6800 */
1501     case 0x0120:   /* GeForce 6800 */
1502     case CHIPSET_NV43:   /* GeForce 6600 */
1503     case CHIPSET_NV44:   /* GeForce 6200 */
1504     case CHIPSET_G72:   /* GeForce 7200, 7300, 7400 */
1505     case CHIPSET_G70:   /* GeForce 7800 */
1506     case CHIPSET_NV45:   /* GeForce 6800 */
1507     case CHIPSET_NV44A:   /* GeForce 6200 */
1508     case CHIPSET_G71:   /* GeForce 7900 */
1509     case CHIPSET_G73:   /* GeForce 7600 */
1510     case CHIPSET_C51:   /* GeForce 6100 */
1511     case CHIPSET_C512: /* Geforce 6100 (nForce 4xx) */
1512          pNv->Architecture =  NV_ARCH_40;
1513          break;
1514     default:
1515          pNv->Architecture =  NV_ARCH_04;
1516          break;
1517     }
1518
1519     pNv->alphaCursor = (pNv->Architecture >= NV_ARCH_10) &&
1520                        ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10);
1521
1522     NVCommonSetup(pScrn);
1523
1524     if (pNv->FBDev) {
1525        pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024;
1526     } else {
1527        pScrn->videoRam = pNv->RamAmountKBytes;
1528     }
1529     xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kBytes\n",
1530                pScrn->videoRam);
1531         
1532     pNv->FbMapSize = pScrn->videoRam * 1024;
1533
1534     /*
1535      * If the driver can do gamma correction, it should call xf86SetGamma()
1536      * here.
1537      */
1538
1539     {
1540         Gamma zeros = {0.0, 0.0, 0.0};
1541
1542         if (!xf86SetGamma(pScrn, zeros)) {
1543             xf86FreeInt10(pNv->pInt);
1544             return FALSE;
1545         }
1546     }
1547
1548     /*
1549      * This is all generally bad.. We need to allocate these areas
1550      */
1551     if(pNv->Architecture >= NV_ARCH_40)
1552        pNv->FbUsableSize = pNv->FbMapSize - (560 * 1024);
1553     else
1554        pNv->FbUsableSize = pNv->FbMapSize - (256 * 1024);
1555     pNv->ScratchBufferSize = (pNv->Architecture < NV_ARCH_10) ? 8192 : 16384;
1556     pNv->ScratchBufferStart = pNv->FbUsableSize - pNv->ScratchBufferSize;
1557     pNv->CursorStart = pNv->ScratchBufferStart - (64*1024);
1558     pNv->FbUsableSize -= pNv->ScratchBufferSize + (64*1024);
1559
1560     /*
1561      * Setup the ClockRanges, which describe what clock ranges are available,
1562      * and what sort of modes they can be used for.
1563      */
1564
1565     clockRanges = xnfcalloc(sizeof(ClockRange), 1);
1566     clockRanges->next = NULL;
1567     clockRanges->minClock = pNv->MinVClockFreqKHz;
1568     clockRanges->maxClock = pNv->MaxVClockFreqKHz;
1569     clockRanges->clockIndex = -1;               /* programmable */
1570     clockRanges->doubleScanAllowed = TRUE;
1571     if((pNv->Architecture == NV_ARCH_20) ||
1572          ((pNv->Architecture == NV_ARCH_10) && 
1573            ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10) &&
1574            ((pNv->Chipset & 0x0ff0) != CHIPSET_NV15)))
1575     {
1576        /* HW is broken */
1577        clockRanges->interlaceAllowed = FALSE;
1578     } else {
1579        clockRanges->interlaceAllowed = TRUE;
1580     }
1581
1582     if(pNv->FlatPanel == 1) {
1583        clockRanges->interlaceAllowed = FALSE;
1584        clockRanges->doubleScanAllowed = FALSE;
1585     }
1586
1587     if(pNv->Architecture < NV_ARCH_10) {
1588        max_width = (pScrn->bitsPerPixel > 16) ? 2032 : 2048;
1589        max_height = 2048;
1590     } else {
1591        max_width = (pScrn->bitsPerPixel > 16) ? 4080 : 4096;
1592        max_height = 4096;
1593     }
1594
1595     /*
1596      * xf86ValidateModes will check that the mode HTotal and VTotal values
1597      * don't exceed the chipset's limit if pScrn->maxHValue and
1598      * pScrn->maxVValue are set.  Since our NVValidMode() already takes
1599      * care of this, we don't worry about setting them here.
1600      */
1601     i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
1602                           pScrn->display->modes, clockRanges,
1603                           NULL, 256, max_width,
1604                           512, 128, max_height,
1605                           pScrn->display->virtualX,
1606                           pScrn->display->virtualY,
1607                           pNv->ScratchBufferStart,
1608                           LOOKUP_BEST_REFRESH);
1609
1610     if (i < 1 && pNv->FBDev) {
1611         fbdevHWUseBuildinMode(pScrn);
1612         pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */
1613         i = 1;
1614     }
1615     if (i == -1) {
1616         xf86FreeInt10(pNv->pInt);
1617         NVFreeRec(pScrn);
1618         return FALSE;
1619     }
1620
1621     /* Prune the modes marked as invalid */
1622     xf86PruneDriverModes(pScrn);
1623
1624     if (i == 0 || pScrn->modes == NULL) {
1625         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
1626         xf86FreeInt10(pNv->pInt);
1627         NVFreeRec(pScrn);
1628         return FALSE;
1629     }
1630
1631     /*
1632      * Set the CRTC parameters for all of the modes based on the type
1633      * of mode, and the chipset's interlace requirements.
1634      *
1635      * Calling this is required if the mode->Crtc* values are used by the
1636      * driver and if the driver doesn't provide code to set them.  They
1637      * are not pre-initialised at all.
1638      */
1639     xf86SetCrtcForModes(pScrn, 0);
1640
1641     /* Set the current mode to the first in the list */
1642     pScrn->currentMode = pScrn->modes;
1643
1644     /* Print the list of modes being used */
1645     xf86PrintModes(pScrn);
1646
1647     /* Set display resolution */
1648     xf86SetDpi(pScrn, 0, 0);
1649
1650
1651     /*
1652      * XXX This should be taken into account in some way in the mode valdation
1653      * section.
1654      */
1655
1656     if (xf86LoadSubModule(pScrn, "fb") == NULL) {
1657         xf86FreeInt10(pNv->pInt);
1658         NVFreeRec(pScrn);
1659         return FALSE;
1660     }
1661
1662     xf86LoaderReqSymLists(fbSymbols, NULL);
1663     
1664     /* Load XAA if needed */
1665     if (!pNv->NoAccel) {
1666         if (!xf86LoadSubModule(pScrn, pNv->useEXA ? "exa" : "xaa")) {
1667             xf86FreeInt10(pNv->pInt);
1668             NVFreeRec(pScrn);
1669             return FALSE;
1670         }
1671         xf86LoaderReqSymLists(xaaSymbols, NULL);
1672     }
1673
1674     /* Load ramdac if needed */
1675     if (pNv->HWCursor) {
1676         if (!xf86LoadSubModule(pScrn, "ramdac")) {
1677             xf86FreeInt10(pNv->pInt);
1678             NVFreeRec(pScrn);
1679             return FALSE;
1680         }
1681         xf86LoaderReqSymLists(ramdacSymbols, NULL);
1682     }
1683
1684     /* Load shadowfb if needed */
1685     if (pNv->ShadowFB) {
1686         if (!xf86LoadSubModule(pScrn, "shadowfb")) {
1687             xf86FreeInt10(pNv->pInt);
1688             NVFreeRec(pScrn);
1689             return FALSE;
1690         }
1691         xf86LoaderReqSymLists(shadowSymbols, NULL);
1692     }
1693
1694     pNv->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
1695     pNv->CurrentLayout.depth = pScrn->depth;
1696     pNv->CurrentLayout.displayWidth = pScrn->displayWidth;
1697     pNv->CurrentLayout.weight.red = pScrn->weight.red;
1698     pNv->CurrentLayout.weight.green = pScrn->weight.green;
1699     pNv->CurrentLayout.weight.blue = pScrn->weight.blue;
1700     pNv->CurrentLayout.mode = pScrn->currentMode;
1701
1702     xf86FreeInt10(pNv->pInt);
1703
1704     pNv->pInt = NULL;
1705     return TRUE;
1706 }
1707
1708
1709 /*
1710  * Map the framebuffer and MMIO memory.
1711  */
1712
1713 static Bool
1714 NVMapMem(ScrnInfoPtr pScrn)
1715 {
1716     NVPtr pNv;
1717         
1718     pNv = NVPTR(pScrn);
1719
1720     pNv->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
1721                                  pNv->PciTag, pNv->FbAddress,
1722                                  pNv->FbMapSize);
1723     if (pNv->FbBase == NULL)
1724         return FALSE;
1725
1726     pNv->FbStart = pNv->FbBase;
1727
1728     return TRUE;
1729 }
1730
1731 Bool
1732 NVMapMemFBDev(ScrnInfoPtr pScrn)
1733 {
1734     NVPtr pNv;
1735
1736     pNv = NVPTR(pScrn);
1737
1738     pNv->FbBase = fbdevHWMapVidmem(pScrn);
1739     if (pNv->FbBase == NULL)
1740         return FALSE;
1741
1742     pNv->FbStart = pNv->FbBase;
1743
1744     return TRUE;
1745 }
1746
1747 /*
1748  * Unmap the framebuffer and MMIO memory.
1749  */
1750
1751 static Bool
1752 NVUnmapMem(ScrnInfoPtr pScrn)
1753 {
1754     NVPtr pNv;
1755     
1756     pNv = NVPTR(pScrn);
1757
1758     xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pNv->FbBase, pNv->FbMapSize);
1759     pNv->FbBase = NULL;
1760     pNv->FbStart = NULL;
1761
1762     return TRUE;
1763 }
1764
1765
1766 /*
1767  * Initialise a new mode. 
1768  */
1769
1770 static Bool
1771 NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1772 {
1773     vgaHWPtr hwp = VGAHWPTR(pScrn);
1774     vgaRegPtr vgaReg;
1775     NVPtr pNv = NVPTR(pScrn);
1776     NVRegPtr nvReg;
1777
1778     /* Initialise the ModeReg values */
1779     if (!vgaHWInit(pScrn, mode))
1780         return FALSE;
1781     pScrn->vtSema = TRUE;
1782
1783     vgaReg = &hwp->ModeReg;
1784     nvReg = &pNv->ModeReg;
1785
1786     if(!NVDACInit(pScrn, mode))
1787         return FALSE;
1788
1789     NVLockUnlock(pNv, 0);
1790     if(pNv->twoHeads) {
1791         VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
1792         VGA_WR08(pNv->PCIO, 0x03D5, nvReg->crtcOwner);
1793         NVLockUnlock(pNv, 0);
1794     }
1795
1796     /* Program the registers */
1797     vgaHWProtect(pScrn, TRUE);
1798
1799     NVDACRestore(pScrn, vgaReg, nvReg, FALSE);
1800
1801 #if X_BYTE_ORDER == X_BIG_ENDIAN
1802     /* turn on LFB swapping */
1803     {
1804         unsigned char tmp;
1805
1806         VGA_WR08(pNv->PCIO, 0x3d4, 0x46);
1807         tmp = VGA_RD08(pNv->PCIO, 0x3d5);
1808         tmp |= (1 << 7);
1809         VGA_WR08(pNv->PCIO, 0x3d5, tmp);
1810     }
1811 #endif
1812
1813     NVResetGraphics(pScrn);
1814
1815     vgaHWProtect(pScrn, FALSE);
1816
1817     pNv->CurrentLayout.mode = mode;
1818
1819     return TRUE;
1820 }
1821
1822 /*
1823  * Restore the initial (text) mode.
1824  */
1825 static void 
1826 NVRestore(ScrnInfoPtr pScrn)
1827 {
1828     vgaHWPtr hwp = VGAHWPTR(pScrn);
1829     vgaRegPtr vgaReg = &hwp->SavedReg;
1830     NVPtr pNv = NVPTR(pScrn);
1831     NVRegPtr nvReg = &pNv->SavedReg;
1832
1833     NVLockUnlock(pNv, 0);
1834
1835     if(pNv->twoHeads) {
1836         VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
1837         VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3);
1838         NVLockUnlock(pNv, 0);
1839     }
1840
1841     /* Only restore text mode fonts/text for the primary card */
1842     vgaHWProtect(pScrn, TRUE);
1843     NVDACRestore(pScrn, vgaReg, nvReg, pNv->Primary);
1844     if(pNv->twoHeads) {
1845         VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
1846         VGA_WR08(pNv->PCIO, 0x03D5, pNv->vtOWNER);
1847     }
1848     vgaHWProtect(pScrn, FALSE);
1849 }
1850
1851 static void NVBacklightEnable(NVPtr pNv,  Bool on)
1852 {
1853     /* This is done differently on each laptop.  Here we
1854        define the ones we know for sure. */
1855
1856 #if defined(__powerpc__)
1857     if((pNv->Chipset == 0x10DE0179) || 
1858        (pNv->Chipset == 0x10DE0189) || 
1859        (pNv->Chipset == 0x10DE0329))
1860     {
1861        /* NV17,18,34 Apple iMac, iBook, PowerBook */
1862       CARD32 tmp_pmc, tmp_pcrt;
1863       tmp_pmc = pNv->PMC[0x10F0/4] & 0x7FFFFFFF;
1864       tmp_pcrt = pNv->PCRTC0[0x081C/4] & 0xFFFFFFFC;
1865       if(on) {
1866           tmp_pmc |= (1 << 31);
1867           tmp_pcrt |= 0x1;
1868       }
1869       pNv->PMC[0x10F0/4] = tmp_pmc;
1870       pNv->PCRTC0[0x081C/4] = tmp_pcrt;
1871     }
1872 #endif
1873     
1874     if(pNv->LVDS) {
1875        if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11)) {
1876            pNv->PMC[0x130C/4] = on ? 3 : 7; 
1877        }
1878     } else {
1879        CARD32 fpcontrol;
1880
1881        fpcontrol = pNv->PRAMDAC[0x0848/4] & 0xCfffffCC;
1882
1883        /* cut the TMDS output */
1884        if(on) fpcontrol |= pNv->fpSyncs;
1885        else fpcontrol |= 0x20000022;
1886
1887        pNv->PRAMDAC[0x0848/4] = fpcontrol;
1888     }
1889 }
1890
1891 static void
1892 NVDPMSSetLCD(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
1893 {
1894   NVPtr pNv = NVPTR(pScrn);
1895
1896   if (!pScrn->vtSema) return;
1897
1898   vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
1899
1900   switch (PowerManagementMode) {
1901   case DPMSModeStandby:  /* HSync: Off, VSync: On */
1902   case DPMSModeSuspend:  /* HSync: On, VSync: Off */
1903   case DPMSModeOff:      /* HSync: Off, VSync: Off */
1904     NVBacklightEnable(pNv, 0);
1905     break;
1906   case DPMSModeOn:       /* HSync: On, VSync: On */
1907     NVBacklightEnable(pNv, 1);
1908   default:
1909     break;
1910   }
1911 }
1912
1913
1914 static void
1915 NVDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
1916 {
1917   unsigned char crtc1A;
1918   vgaHWPtr hwp = VGAHWPTR(pScrn);
1919
1920   if (!pScrn->vtSema) return;
1921
1922   crtc1A = hwp->readCrtc(hwp, 0x1A) & ~0xC0;
1923
1924   switch (PowerManagementMode) {
1925   case DPMSModeStandby:  /* HSync: Off, VSync: On */
1926     crtc1A |= 0x80;
1927     break;
1928   case DPMSModeSuspend:  /* HSync: On, VSync: Off */
1929     crtc1A |= 0x40;
1930     break;
1931   case DPMSModeOff:      /* HSync: Off, VSync: Off */
1932     crtc1A |= 0xC0;
1933     break;
1934   case DPMSModeOn:       /* HSync: On, VSync: On */
1935   default:
1936     break;
1937   }
1938
1939   /* vgaHWDPMSSet will merely cut the dac output */
1940   vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
1941
1942   hwp->writeCrtc(hwp, 0x1A, crtc1A);
1943 }
1944
1945
1946 /* Mandatory */
1947
1948 /* This gets called at the start of each server generation */
1949
1950 static Bool
1951 NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
1952 {
1953     ScrnInfoPtr pScrn;
1954     vgaHWPtr hwp;
1955     NVPtr pNv;
1956     int ret;
1957     VisualPtr visual;
1958     unsigned char *FBStart;
1959     int width, height, displayWidth, offscreenHeight, shadowHeight;
1960     BoxRec AvailFBArea;
1961
1962     /* 
1963      * First get the ScrnInfoRec
1964      */
1965     pScrn = xf86Screens[pScreen->myNum];
1966
1967     hwp = VGAHWPTR(pScrn);
1968     pNv = NVPTR(pScrn);
1969
1970     /* Map the NV memory and MMIO areas */
1971     if (pNv->FBDev) {
1972         if (!NVMapMemFBDev(pScrn)) {
1973             return FALSE;
1974         }
1975     } else {
1976         if (!NVMapMem(pScrn)) {
1977             return FALSE;
1978          }
1979     }
1980
1981     /* Map the VGA memory when the primary video */
1982     if (pNv->Primary && !pNv->FBDev) {
1983         hwp->MapSize = 0x10000;
1984         if (!vgaHWMapMem(pScrn))
1985             return FALSE;
1986     }
1987
1988         /* Init DRM - Alloc FIFO, setup graphics objects */
1989         if (!NVInitDma(pScrn))
1990                 return FALSE;
1991         
1992     if (pNv->FBDev) {
1993         fbdevHWSave(pScrn);
1994         if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
1995             return FALSE;
1996     } else {
1997         /* Save the current state */
1998         NVSave(pScrn);
1999         /* Initialise the first mode */
2000         if (!NVModeInit(pScrn, pScrn->currentMode)) {
2001             return FALSE;
2002     }
2003     }
2004
2005     /* Darken the screen for aesthetic reasons and set the viewport */
2006     NVSaveScreen(pScreen, SCREEN_SAVER_ON);
2007     pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
2008
2009     /*
2010      * The next step is to setup the screen's visuals, and initialise the
2011      * framebuffer code.  In cases where the framebuffer's default
2012      * choices for things like visual layouts and bits per RGB are OK,
2013      * this may be as simple as calling the framebuffer's ScreenInit()
2014      * function.  If not, the visuals will need to be setup before calling
2015      * a fb ScreenInit() function and fixed up after.
2016      *
2017      * For most PC hardware at depths >= 8, the defaults that fb uses
2018      * are not appropriate.  In this driver, we fixup the visuals after.
2019      */
2020
2021     /*
2022      * Reset the visual list.
2023      */
2024     miClearVisualTypes();
2025
2026     /* Setup the visuals we support. */
2027
2028     if (!miSetVisualTypes(pScrn->depth, 
2029                           miGetDefaultVisualMask(pScrn->depth), 8,
2030                           pScrn->defaultVisual))
2031           return FALSE;
2032     if (!miSetPixmapDepths ()) return FALSE;
2033
2034     /*
2035      * Call the framebuffer layer's ScreenInit function, and fill in other
2036      * pScreen fields.
2037      */
2038
2039     width = pScrn->virtualX;
2040     height = pScrn->virtualY;
2041     displayWidth = pScrn->displayWidth;
2042
2043
2044     if(pNv->Rotate) {
2045         height = pScrn->virtualX;
2046         width = pScrn->virtualY;
2047     }
2048
2049     /* If RandR rotation is enabled, leave enough space in the
2050      * framebuffer for us to rotate the screen dimensions without
2051      * changing the pitch.
2052      */
2053     if(pNv->RandRRotation)
2054         shadowHeight = max(width, height);
2055     else
2056         shadowHeight = height;
2057
2058     if(pNv->ShadowFB) {
2059         pNv->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
2060         pNv->ShadowPtr = xalloc(pNv->ShadowPitch * shadowHeight);
2061         displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3);
2062         FBStart = pNv->ShadowPtr;
2063     } else {
2064         pNv->ShadowPtr = NULL;
2065         FBStart = pNv->FbStart;
2066     }
2067
2068     switch (pScrn->bitsPerPixel) {
2069         case 8:
2070         case 16:
2071         case 32:
2072             ret = fbScreenInit(pScreen, FBStart, width, height,
2073                                pScrn->xDpi, pScrn->yDpi,
2074                                displayWidth, pScrn->bitsPerPixel);
2075             break;
2076         default:
2077             xf86DrvMsg(scrnIndex, X_ERROR,
2078                        "Internal error: invalid bpp (%d) in NVScreenInit\n",
2079                        pScrn->bitsPerPixel);
2080             ret = FALSE;
2081             break;
2082     }
2083     if (!ret)
2084         return FALSE;
2085
2086     if (pScrn->bitsPerPixel > 8) {
2087         /* Fixup RGB ordering */
2088         visual = pScreen->visuals + pScreen->numVisuals;
2089         while (--visual >= pScreen->visuals) {
2090             if ((visual->class | DynamicClass) == DirectColor) {
2091                 visual->offsetRed = pScrn->offset.red;
2092                 visual->offsetGreen = pScrn->offset.green;
2093                 visual->offsetBlue = pScrn->offset.blue;
2094                 visual->redMask = pScrn->mask.red;
2095                 visual->greenMask = pScrn->mask.green;
2096                 visual->blueMask = pScrn->mask.blue;
2097             }
2098         }
2099     }
2100
2101     fbPictureInit (pScreen, 0, 0);
2102     
2103     xf86SetBlackWhitePixels(pScreen);
2104
2105     if(!pNv->ShadowFB) /* hardware cursor needs to wrap this layer */
2106         NVDGAInit(pScreen);
2107
2108     offscreenHeight = pNv->ScratchBufferStart /
2109                      (pScrn->displayWidth * pScrn->bitsPerPixel >> 3);
2110     if(offscreenHeight > 32767)
2111         offscreenHeight = 32767;
2112
2113     if (!pNv->useEXA) {
2114     AvailFBArea.x1 = 0;
2115     AvailFBArea.y1 = 0;
2116     AvailFBArea.x2 = pScrn->displayWidth;
2117     AvailFBArea.y2 = offscreenHeight;
2118     xf86InitFBManager(pScreen, &AvailFBArea);
2119     }
2120     
2121     if (!pNv->NoAccel) {
2122         if (pNv->useEXA)
2123             NVExaInit(pScreen);
2124         else /* XAA */
2125             NVXaaInit(pScreen);
2126     }
2127     NVResetGraphics(pScrn);
2128     
2129     miInitializeBackingStore(pScreen);
2130     xf86SetBackingStore(pScreen);
2131     xf86SetSilkenMouse(pScreen);
2132
2133     /* Initialize software cursor.  
2134         Must precede creation of the default colormap */
2135     miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
2136
2137     /* Initialize HW cursor layer. 
2138         Must follow software cursor initialization*/
2139     if (pNv->HWCursor) { 
2140         if(!NVCursorInit(pScreen))
2141             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
2142                 "Hardware cursor initialization failed\n");
2143     }
2144
2145     /* Initialise default colourmap */
2146     if (!miCreateDefColormap(pScreen))
2147         return FALSE;
2148
2149     /* Initialize colormap layer.  
2150         Must follow initialization of the default colormap */
2151     if(!xf86HandleColormaps(pScreen, 256, 8,
2152         (pNv->FBDev ? fbdevHWLoadPaletteWeak() : NVDACLoadPalette), 
2153         NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
2154         return FALSE;
2155
2156     if(pNv->ShadowFB) {
2157         RefreshAreaFuncPtr refreshArea = NVRefreshArea;
2158
2159         if(pNv->Rotate || pNv->RandRRotation) {
2160            pNv->PointerMoved = pScrn->PointerMoved;
2161            if(pNv->Rotate)
2162                pScrn->PointerMoved = NVPointerMoved;
2163
2164            switch(pScrn->bitsPerPixel) {
2165                case 8:  refreshArea = NVRefreshArea8;   break;
2166                case 16: refreshArea = NVRefreshArea16;  break;
2167                case 32: refreshArea = NVRefreshArea32;  break;
2168            }
2169            if(!pNv->RandRRotation) {
2170                xf86DisableRandR();
2171                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2172                           "Driver rotation enabled, RandR disabled\n");
2173            }
2174         }
2175
2176         ShadowFBInit(pScreen, refreshArea);
2177     }
2178
2179     if(pNv->FlatPanel)
2180        xf86DPMSInit(pScreen, NVDPMSSetLCD, 0);
2181     else
2182        xf86DPMSInit(pScreen, NVDPMSSet, 0);
2183     
2184     pScrn->memPhysBase = pNv->FbAddress;
2185     pScrn->fbOffset = 0;
2186
2187     if(pNv->Rotate == 0 && !pNv->RandRRotation)
2188        NVInitVideo(pScreen);
2189
2190     pScreen->SaveScreen = NVSaveScreen;
2191
2192     /* Wrap the current CloseScreen function */
2193     pNv->CloseScreen = pScreen->CloseScreen;
2194     pScreen->CloseScreen = NVCloseScreen;
2195
2196     pNv->BlockHandler = pScreen->BlockHandler;
2197     pScreen->BlockHandler = NVBlockHandler;
2198
2199 #ifdef RANDR
2200     /* Install our DriverFunc.  We have to do it this way instead of using the
2201      * HaveDriverFuncs argument to xf86AddDriver, because InitOutput clobbers
2202      * pScrn->DriverFunc */
2203     pScrn->DriverFunc = NVDriverFunc;
2204 #endif
2205
2206     /* Report any unused options (only for the first generation) */
2207     if (serverGeneration == 1) {
2208         xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
2209     }
2210     return TRUE;
2211 }
2212
2213 static Bool
2214 NVSaveScreen(ScreenPtr pScreen, int mode)
2215 {
2216     return vgaHWSaveScreen(pScreen, mode);
2217 }
2218
2219 static void
2220 NVSave(ScrnInfoPtr pScrn)
2221 {
2222     NVPtr pNv = NVPTR(pScrn);
2223     NVRegPtr nvReg = &pNv->SavedReg;
2224     vgaHWPtr pVga = VGAHWPTR(pScrn);
2225     vgaRegPtr vgaReg = &pVga->SavedReg;
2226
2227     NVLockUnlock(pNv, 0);
2228     if(pNv->twoHeads) {
2229         VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
2230         VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3);
2231         NVLockUnlock(pNv, 0);
2232     }
2233
2234     NVDACSave(pScrn, vgaReg, nvReg, pNv->Primary);
2235 }
2236
2237 #ifdef RANDR
2238 static Bool
2239 NVRandRGetInfo(ScrnInfoPtr pScrn, Rotation *rotations)
2240 {
2241     NVPtr pNv = NVPTR(pScrn);
2242
2243     if(pNv->RandRRotation)
2244        *rotations = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_270;
2245     else
2246        *rotations = RR_Rotate_0;
2247
2248     return TRUE;
2249 }
2250
2251 static Bool
2252 NVRandRSetConfig(ScrnInfoPtr pScrn, xorgRRConfig *config)
2253 {
2254     NVPtr pNv = NVPTR(pScrn);
2255
2256     switch(config->rotation) {
2257         case RR_Rotate_0:
2258             pNv->Rotate = 0;
2259             pScrn->PointerMoved = pNv->PointerMoved;
2260             break;
2261
2262         case RR_Rotate_90:
2263             pNv->Rotate = -1;
2264             pScrn->PointerMoved = NVPointerMoved;
2265             break;
2266
2267         case RR_Rotate_270:
2268             pNv->Rotate = 1;
2269             pScrn->PointerMoved = NVPointerMoved;
2270             break;
2271
2272         default:
2273             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2274                     "Unexpected rotation in NVRandRSetConfig!\n");
2275             pNv->Rotate = 0;
2276             pScrn->PointerMoved = pNv->PointerMoved;
2277             return FALSE;
2278     }
2279
2280     return TRUE;
2281 }
2282
2283 static Bool
2284 NVDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer data)
2285 {
2286     switch(op) {
2287        case RR_GET_INFO:
2288           return NVRandRGetInfo(pScrn, (Rotation*)data);
2289        case RR_SET_CONFIG:
2290           return NVRandRSetConfig(pScrn, (xorgRRConfig*)data);
2291        default:
2292           return FALSE;
2293     }
2294
2295     return FALSE;
2296 }
2297 #endif