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