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