Config options for cmdbuf location/size.
[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(nouveauSetup);
473
474 static XF86ModuleVersionInfo nouveauVersRec =
475 {
476     "nouveau",
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 nouveauModuleData = { &nouveauVersRec, nouveauSetup, NULL };
489
490
491 /*
492  * This is intentionally screen-independent.  It indicates the binding
493  * choice made in the first PreInit.
494  */
495 static int pix24bpp = 0;
496
497 NVAllocRec *NVAllocateMemory(NVPtr pNv, int type, int size)
498 {
499         drm_nouveau_mem_alloc_t memalloc;
500         NVAllocRec *mem;
501
502         mem = malloc(sizeof(NVAllocRec));
503         if (!mem)
504                 return NULL;
505         mem->type = type | NOUVEAU_MEM_MAPPED;
506         mem->size = size;
507
508         memalloc.flags         = mem->type;
509         memalloc.size          = mem->size;
510         memalloc.alignment     = 0;
511         memalloc.region_offset = &mem->offset;
512         if (drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_MEM_ALLOC, &memalloc,
513                                 sizeof(memalloc))) {
514                 ErrorF("NOUVEAU_MEM_ALLOC failed.  flags=0x%08x, size=%d (%d)\n",
515                                 mem->type, mem->size, errno);
516                 free(mem);
517                 return NULL;
518         }
519
520         if (drmMap(pNv->drm_fd, mem->offset, mem->size, &mem->map)) {
521                 ErrorF("drmMap() failed. offset=0x%llx, size=%d (%d)\n",
522                                 mem->offset, mem->size, errno);
523                 mem->map  = NULL;
524                 NVFreeMemory(pNv, mem);
525                 return NULL;
526         }
527
528         return mem;
529 }
530
531 void NVFreeMemory(NVPtr pNv, NVAllocRec *mem)
532 {
533         drm_nouveau_mem_free_t memfree;
534
535         if (mem) {
536                 if (mem->map) {
537                         if (drmUnmap(mem->map, mem->size))
538                                 ErrorF("drmUnmap() failed. map=%p, size=%d\n", mem->map, mem->size);
539                 }
540
541                 memfree.flags = mem->type;
542                 memfree.region_offset = mem->offset;
543                 if (drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_MEM_FREE, &memfree,
544                                         sizeof(memfree))) {
545                         ErrorF("NOUVEAU_MEM_FREE failed.  flags=0x%08x, offset=0x%llx (%d)\n",
546                                         mem->type, mem->size, errno);
547                 }
548                 free(mem);
549         }
550 }
551
552 static Bool
553 NVGetRec(ScrnInfoPtr pScrn)
554 {
555     /*
556      * Allocate an NVRec, and hook it into pScrn->driverPrivate.
557      * pScrn->driverPrivate is initialised to NULL, so we can check if
558      * the allocation has already been done.
559      */
560     if (pScrn->driverPrivate != NULL)
561         return TRUE;
562
563     pScrn->driverPrivate = xnfcalloc(sizeof(NVRec), 1);
564     /* Initialise it */
565
566     return TRUE;
567 }
568
569 static void
570 NVFreeRec(ScrnInfoPtr pScrn)
571 {
572     if (pScrn->driverPrivate == NULL)
573         return;
574     xfree(pScrn->driverPrivate);
575     pScrn->driverPrivate = NULL;
576 }
577
578
579 static pointer
580 nouveauSetup(pointer module, pointer opts, int *errmaj, int *errmin)
581 {
582     static Bool setupDone = FALSE;
583
584     /* This module should be loaded only once, but check to be sure. */
585
586     if (!setupDone) {
587         setupDone = TRUE;
588         xf86AddDriver(&NV, module, 0);
589
590         /*
591          * Modules that this driver always requires may be loaded here
592          * by calling LoadSubModule().
593          */
594         /*
595          * Tell the loader about symbols from other modules that this module
596          * might refer to.
597          */
598         LoaderRefSymLists(vgahwSymbols, xaaSymbols, exaSymbols, fbSymbols,
599 #ifdef XF86DRI
600                           drmSymbols, 
601 #endif
602                           ramdacSymbols, shadowSymbols, rivaSymbols,
603                           i2cSymbols, ddcSymbols, vbeSymbols,
604                           int10Symbols, NULL);
605
606         /*
607          * The return value must be non-NULL on success even though there
608          * is no TearDownProc.
609          */
610         return (pointer)1;
611     } else {
612         if (errmaj) *errmaj = LDR_ONCEONLY;
613         return NULL;
614     }
615 }
616
617 static const OptionInfoRec *
618 NVAvailableOptions(int chipid, int busid)
619 {
620     if(chipid == 0x12D20018) {
621         if (!xf86LoadOneModule("riva128", NULL)) {
622             return NULL;
623         } else
624             return RivaAvailableOptions(chipid, busid);
625     }
626     
627     return NVOptions;
628 }
629
630 /* Mandatory */
631 static void
632 NVIdentify(int flags)
633 {
634     xf86PrintChipsets(NV_NAME, "driver for NVIDIA chipsets", NVKnownChipsets);
635 }
636
637
638 static Bool
639 NVGetScrnInfoRec(PciChipsets *chips, int chip)
640 {
641     ScrnInfoPtr pScrn;
642
643     pScrn = xf86ConfigPciEntity(NULL, 0, chip,
644                                 chips, NULL, NULL, NULL,
645                                 NULL, NULL);
646
647     if(!pScrn) return FALSE;
648
649     pScrn->driverVersion    = NV_VERSION;
650     pScrn->driverName       = NV_DRIVER_NAME;
651     pScrn->name             = NV_NAME;
652
653     pScrn->Probe            = NVProbe;
654     pScrn->PreInit          = NVPreInit;
655     pScrn->ScreenInit       = NVScreenInit;
656     pScrn->SwitchMode       = NVSwitchMode;
657     pScrn->AdjustFrame      = NVAdjustFrame;
658     pScrn->EnterVT          = NVEnterVT;
659     pScrn->LeaveVT          = NVLeaveVT;
660     pScrn->FreeScreen       = NVFreeScreen;
661     pScrn->ValidMode        = NVValidMode;
662
663     return TRUE;
664 }
665
666 #define MAX_CHIPS MAXSCREENS
667
668
669 static CARD32 
670 NVGetPCIXpressChip (pciVideoPtr pVideo)
671 {
672     volatile CARD32 *regs;
673     CARD32 pciid, pcicmd;
674     PCITAG Tag = ((pciConfigPtr)(pVideo->thisCard))->tag;
675
676     pcicmd = pciReadLong(Tag, PCI_CMD_STAT_REG);
677     pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd | PCI_CMD_MEM_ENABLE);
678     
679     regs = xf86MapPciMem(-1, VIDMEM_MMIO, Tag, pVideo->memBase[0], 0x2000);
680
681     pciid = regs[0x1800/4];
682
683     xf86UnMapVidMem(-1, (pointer)regs, 0x2000);
684
685     pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd);
686
687     if((pciid & 0x0000ffff) == 0x000010DE) 
688        pciid = 0x10DE0000 | (pciid >> 16);
689     else 
690     if((pciid & 0xffff0000) == 0xDE100000) /* wrong endian */
691        pciid = 0x10DE0000 | ((pciid << 8) & 0x0000ff00) |
692                             ((pciid >> 8) & 0x000000ff);
693
694     return pciid;
695 }
696
697
698 /* Mandatory */
699 static Bool
700 NVProbe(DriverPtr drv, int flags)
701 {
702     int i;
703     GDevPtr *devSections;
704     int *usedChips;
705     SymTabRec NVChipsets[MAX_CHIPS + 1];
706     PciChipsets NVPciChipsets[MAX_CHIPS + 1];
707     pciVideoPtr *ppPci;
708     int numDevSections;
709     int numUsed;
710     Bool foundScreen = FALSE;
711
712
713     if ((numDevSections = xf86MatchDevice(NV_DRIVER_NAME, &devSections)) <= 0) 
714         return FALSE;  /* no matching device section */
715
716     if (!(ppPci = xf86GetPciVideoInfo())) 
717         return FALSE;  /* no PCI cards found */
718
719     numUsed = 0;
720
721     /* Create the NVChipsets and NVPciChipsets from found devices */
722     while (*ppPci && (numUsed < MAX_CHIPS)) {
723         if(((*ppPci)->vendor == PCI_VENDOR_NVIDIA_SGS) || 
724            ((*ppPci)->vendor == PCI_VENDOR_NVIDIA)) 
725         {
726             SymTabRec *nvchips = NVKnownChipsets;
727             int pciid = ((*ppPci)->vendor << 16) | (*ppPci)->chipType;
728             int token = pciid;
729
730             if(((token & 0xfff0) == CHIPSET_MISC_BRIDGED) ||
731                ((token & 0xfff0) == CHIPSET_G73_BRIDGED))
732             {
733                 token = NVGetPCIXpressChip(*ppPci);
734             }
735
736             while(nvchips->name) {
737                if(token == nvchips->token)
738                   break;
739                nvchips++;
740             }
741
742             if(nvchips->name) { /* found one */
743                NVChipsets[numUsed].token = pciid;
744                NVChipsets[numUsed].name = nvchips->name;
745                NVPciChipsets[numUsed].numChipset = pciid; 
746                NVPciChipsets[numUsed].PCIid = pciid;
747                NVPciChipsets[numUsed].resList = RES_SHARED_VGA;
748                numUsed++;
749             } else if ((*ppPci)->vendor == PCI_VENDOR_NVIDIA) {
750                /* look for a compatible devices which may be newer than 
751                   the NVKnownChipsets list above.  */
752                switch(token & 0xfff0) {
753                case CHIPSET_NV17:
754                case CHIPSET_NV18:
755                case CHIPSET_NV25:
756                case CHIPSET_NV28:
757                case CHIPSET_NV30:
758                case CHIPSET_NV31:
759                case CHIPSET_NV34:
760                case CHIPSET_NV35:
761                case CHIPSET_NV36:
762                case CHIPSET_NV40:
763                case CHIPSET_NV41:
764                case 0x0120:
765                case CHIPSET_NV43:
766                case CHIPSET_NV44:
767                case 0x0130:
768                case CHIPSET_G72:
769                case CHIPSET_G70:
770                case CHIPSET_NV45:
771                case CHIPSET_NV44A:
772                case 0x0230:
773                case CHIPSET_G71:
774                case CHIPSET_G73:
775                case CHIPSET_C512:
776                    NVChipsets[numUsed].token = pciid;
777                    NVChipsets[numUsed].name = "Unknown NVIDIA chip";
778                    NVPciChipsets[numUsed].numChipset = pciid;
779                    NVPciChipsets[numUsed].PCIid = pciid;
780                    NVPciChipsets[numUsed].resList = RES_SHARED_VGA;
781                    numUsed++;
782                    break;
783                default:  break;  /* we don't recognize it */
784                }
785             }
786         }
787         ppPci++;
788     }
789
790     /* terminate the list */
791     NVChipsets[numUsed].token = -1;
792     NVChipsets[numUsed].name = NULL; 
793     NVPciChipsets[numUsed].numChipset = -1;
794     NVPciChipsets[numUsed].PCIid = -1;
795     NVPciChipsets[numUsed].resList = RES_UNDEFINED;
796
797     numUsed = xf86MatchPciInstances(NV_NAME, 0, NVChipsets, NVPciChipsets,
798                                     devSections, numDevSections, drv,
799                                     &usedChips);
800                         
801     if (numUsed <= 0) 
802         return FALSE;
803
804     if (flags & PROBE_DETECT)
805         foundScreen = TRUE;
806     else for (i = 0; i < numUsed; i++) {
807         pciVideoPtr pPci;
808
809         pPci = xf86GetPciInfoForEntity(usedChips[i]);
810         if(pPci->vendor == PCI_VENDOR_NVIDIA_SGS) {
811             if (!xf86LoadDrvSubModule(drv, "riva128")) {
812                   continue;
813             }
814             xf86LoaderReqSymLists(rivaSymbols, NULL);
815             if(RivaGetScrnInfoRec(NVPciChipsets, usedChips[i]))
816                 foundScreen = TRUE;
817         } else {
818             if(NVGetScrnInfoRec(NVPciChipsets, usedChips[i])) 
819                 foundScreen = TRUE;
820         }    
821     }
822
823     xfree(devSections);
824     xfree(usedChips);
825
826     return foundScreen;
827 }
828
829 /* Usually mandatory */
830 Bool
831 NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
832 {
833     return NVModeInit(xf86Screens[scrnIndex], mode);
834 }
835
836 /*
837  * This function is used to initialize the Start Address - the first
838  * displayed location in the video memory.
839  */
840 /* Usually mandatory */
841 void 
842 NVAdjustFrame(int scrnIndex, int x, int y, int flags)
843 {
844     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
845     int startAddr;
846     NVPtr pNv = NVPTR(pScrn);
847     NVFBLayout *pLayout = &pNv->CurrentLayout;
848
849     startAddr = (((y*pLayout->displayWidth)+x)*(pLayout->bitsPerPixel/8));
850         startAddr += (pNv->FB->offset - pNv->VRAMPhysical);
851     NVSetStartAddress(pNv, startAddr);
852 }
853
854
855 /*
856  * This is called when VT switching back to the X server.  Its job is
857  * to reinitialise the video mode.
858  *
859  * We may wish to unmap video/MMIO memory too.
860  */
861
862 /* Mandatory */
863 static Bool
864 NVEnterVT(int scrnIndex, int flags)
865 {
866     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
867     NVPtr pNv = NVPTR(pScrn);
868
869     if (!NVModeInit(pScrn, pScrn->currentMode))
870         return FALSE;
871     NVAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
872
873     if(pNv->overlayAdaptor)
874         NVResetVideo(pScrn);
875     return TRUE;
876 }
877
878 /*
879  * This is called when VT switching away from the X server.  Its job is
880  * to restore the previous (text) mode.
881  *
882  * We may wish to remap video/MMIO memory too.
883  */
884
885 /* Mandatory */
886 static void
887 NVLeaveVT(int scrnIndex, int flags)
888 {
889     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
890     NVPtr pNv = NVPTR(pScrn);
891
892     NVSync(pScrn);
893     NVRestore(pScrn);
894     NVLockUnlock(pNv, 1);
895 }
896
897
898
899 static void 
900 NVBlockHandler (
901     int i, 
902     pointer blockData, 
903     pointer pTimeout,
904     pointer pReadmask
905 )
906 {
907     ScreenPtr     pScreen = screenInfo.screens[i];
908     ScrnInfoPtr   pScrnInfo = xf86Screens[i];
909     NVPtr         pNv = NVPTR(pScrnInfo);
910
911     if (pNv->DMAKickoffCallback)
912         (*pNv->DMAKickoffCallback)(pNv);
913     
914     pScreen->BlockHandler = pNv->BlockHandler;
915     (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
916     pScreen->BlockHandler = NVBlockHandler;
917
918     if (pNv->VideoTimerCallback) 
919         (*pNv->VideoTimerCallback)(pScrnInfo, currentTime.milliseconds);
920
921 }
922
923
924 /*
925  * This is called at the end of each server generation.  It restores the
926  * original (text) mode.  It should also unmap the video memory, and free
927  * any per-generation data allocated by the driver.  It should finish
928  * by unwrapping and calling the saved CloseScreen function.
929  */
930
931 /* Mandatory */
932 static Bool
933 NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
934 {
935     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
936     NVPtr pNv = NVPTR(pScrn);
937
938     if (pScrn->vtSema) {
939         NVSync(pScrn);
940         NVRestore(pScrn);
941         NVLockUnlock(pNv, 1);
942     }
943
944     NVUnmapMem(pScrn);
945     vgaHWUnmapMem(pScrn);
946     if (pNv->AccelInfoRec)
947         XAADestroyInfoRec(pNv->AccelInfoRec);
948     if (pNv->CursorInfoRec)
949         xf86DestroyCursorInfoRec(pNv->CursorInfoRec);
950     if (pNv->ShadowPtr)
951         xfree(pNv->ShadowPtr);
952     if (pNv->overlayAdaptor)
953         xfree(pNv->overlayAdaptor);
954     if (pNv->blitAdaptor)
955         xfree(pNv->blitAdaptor);
956
957     pScrn->vtSema = FALSE;
958     pScreen->CloseScreen = pNv->CloseScreen;
959     pScreen->BlockHandler = pNv->BlockHandler;
960     return (*pScreen->CloseScreen)(scrnIndex, pScreen);
961 }
962
963 /* Free up any persistent data structures */
964
965 /* Optional */
966 static void
967 NVFreeScreen(int scrnIndex, int flags)
968 {
969     /*
970      * This only gets called when a screen is being deleted.  It does not
971      * get called routinely at the end of a server generation.
972      */
973     if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
974         vgaHWFreeHWRec(xf86Screens[scrnIndex]);
975     NVFreeRec(xf86Screens[scrnIndex]);
976 }
977
978
979 /* Checks if a mode is suitable for the selected chipset. */
980
981 /* Optional */
982 static ModeStatus
983 NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
984 {
985     NVPtr pNv = NVPTR(xf86Screens[scrnIndex]);
986
987     if(pNv->fpWidth && pNv->fpHeight)
988       if((pNv->fpWidth < mode->HDisplay) || (pNv->fpHeight < mode->VDisplay))
989         return (MODE_PANEL);
990
991     return (MODE_OK);
992 }
993
994 static void
995 nvProbeDDC(ScrnInfoPtr pScrn, int index)
996 {
997     vbeInfoPtr pVbe;
998
999     if (xf86LoadSubModule(pScrn, "vbe")) {
1000         pVbe = VBEInit(NULL,index);
1001         ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
1002         vbeFree(pVbe);
1003     }
1004 }
1005
1006
1007 Bool NVI2CInit(ScrnInfoPtr pScrn)
1008 {
1009     char *mod = "i2c";
1010
1011     if (xf86LoadSubModule(pScrn, mod)) {
1012         xf86LoaderReqSymLists(i2cSymbols,NULL);
1013
1014         mod = "ddc";
1015         if(xf86LoadSubModule(pScrn, mod)) {
1016             xf86LoaderReqSymLists(ddcSymbols, NULL);
1017             return NVDACi2cInit(pScrn);
1018         } 
1019     }
1020
1021     xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1022               "Couldn't load %s module.  DDC probing can't be done\n", mod);
1023
1024     return FALSE;
1025 }
1026
1027 /* Mandatory */
1028 Bool
1029 NVPreInit(ScrnInfoPtr pScrn, int flags)
1030 {
1031     NVPtr pNv;
1032     MessageType from;
1033     int i, max_width, max_height;
1034     ClockRangePtr clockRanges;
1035     const char *s;
1036
1037     if (flags & PROBE_DETECT) {
1038         EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
1039
1040         if (!pEnt)
1041             return FALSE;
1042
1043         i = pEnt->index;
1044         xfree(pEnt);
1045
1046         nvProbeDDC(pScrn, i);
1047         return TRUE;
1048     }
1049
1050     /*
1051      * Note: This function is only called once at server startup, and
1052      * not at the start of each server generation.  This means that
1053      * only things that are persistent across server generations can
1054      * be initialised here.  xf86Screens[] is (pScrn is a pointer to one
1055      * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()  
1056      * are too, and should be used for data that must persist across
1057      * server generations.
1058      *
1059      * Per-generation data should be allocated with
1060      * AllocateScreenPrivateIndex() from the ScreenInit() function.
1061      */
1062
1063     /* Check the number of entities, and fail if it isn't one. */
1064     if (pScrn->numEntities != 1)
1065         return FALSE;
1066
1067     /* Allocate the NVRec driverPrivate */
1068     if (!NVGetRec(pScrn)) {
1069         return FALSE;
1070     }
1071     pNv = NVPTR(pScrn);
1072
1073     /* Get the entity, and make sure it is PCI. */
1074     pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
1075     if (pNv->pEnt->location.type != BUS_PCI)
1076         return FALSE;
1077  
1078     /* Find the PCI info for this screen */
1079     pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index);
1080     pNv->PciTag = pciTag(pNv->PciInfo->bus, pNv->PciInfo->device,
1081                           pNv->PciInfo->func);
1082
1083     pNv->Primary = xf86IsPrimaryPci(pNv->PciInfo);
1084
1085     /* Initialize the card through int10 interface if needed */
1086     if (xf86LoadSubModule(pScrn, "int10")) {
1087         xf86LoaderReqSymLists(int10Symbols, NULL);
1088 #if !defined(__alpha__) && !defined(__powerpc__)
1089         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");
1090         pNv->pInt = xf86InitInt10(pNv->pEnt->index);
1091 #endif
1092     }
1093    
1094     xf86SetOperatingState(resVgaIo, pNv->pEnt->index, ResUnusedOpr);
1095     xf86SetOperatingState(resVgaMem, pNv->pEnt->index, ResDisableOpr);
1096
1097     /* Set pScrn->monitor */
1098     pScrn->monitor = pScrn->confScreen->monitor;
1099
1100     /*
1101      * Set the Chipset and ChipRev, allowing config file entries to
1102      * override.
1103      */
1104     if (pNv->pEnt->device->chipset && *pNv->pEnt->device->chipset) {
1105         pScrn->chipset = pNv->pEnt->device->chipset;
1106         pNv->Chipset = xf86StringToToken(NVKnownChipsets, pScrn->chipset);
1107         from = X_CONFIG;
1108     } else if (pNv->pEnt->device->chipID >= 0) {
1109         pNv->Chipset = pNv->pEnt->device->chipID;
1110         pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, 
1111                                                    pNv->Chipset);
1112         from = X_CONFIG;
1113         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
1114                    pNv->Chipset);
1115     } else {
1116         from = X_PROBED;
1117         pNv->Chipset = (pNv->PciInfo->vendor << 16) | pNv->PciInfo->chipType;
1118
1119         if(((pNv->Chipset & 0xfff0) == CHIPSET_MISC_BRIDGED) ||
1120            ((pNv->Chipset & 0xfff0) == CHIPSET_G73_BRIDGED))
1121         {
1122             pNv->Chipset = NVGetPCIXpressChip(pNv->PciInfo);
1123         }
1124
1125         pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, 
1126                                                    pNv->Chipset);
1127         if(!pScrn->chipset)
1128           pScrn->chipset = "Unknown NVIDIA chipset";
1129     }
1130
1131     if (pNv->pEnt->device->chipRev >= 0) {
1132         pNv->ChipRev = pNv->pEnt->device->chipRev;
1133         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
1134                    pNv->ChipRev);
1135     } else {
1136         pNv->ChipRev = pNv->PciInfo->chipRev;
1137     }
1138
1139     /*
1140      * This shouldn't happen because such problems should be caught in
1141      * NVProbe(), but check it just in case.
1142      */
1143     if (pScrn->chipset == NULL) {
1144         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1145                    "ChipID 0x%04X is not recognised\n", pNv->Chipset);
1146         xf86FreeInt10(pNv->pInt);
1147         return FALSE;
1148     }
1149     if (pNv->Chipset < 0) {
1150         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1151                    "Chipset \"%s\" is not recognised\n", pScrn->chipset);
1152         xf86FreeInt10(pNv->pInt);
1153         return FALSE;
1154     }
1155
1156     xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
1157
1158
1159     /*
1160      * The first thing we should figure out is the depth, bpp, etc.
1161      */
1162
1163     if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
1164         xf86FreeInt10(pNv->pInt);
1165         return FALSE;
1166     } else {
1167         /* Check that the returned depth is one we support */
1168         switch (pScrn->depth) {
1169             case 8:
1170             case 15:
1171             case 16:
1172             case 24:
1173                 /* OK */
1174                 break;
1175             default:
1176                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1177                     "Given depth (%d) is not supported by this driver\n",
1178                     pScrn->depth);
1179                 xf86FreeInt10(pNv->pInt);
1180                 return FALSE;
1181         }
1182     }
1183     xf86PrintDepthBpp(pScrn);
1184
1185     /* Get the depth24 pixmap format */
1186     if (pScrn->depth == 24 && pix24bpp == 0)
1187         pix24bpp = xf86GetBppFromDepth(pScrn, 24);
1188
1189     /*
1190      * This must happen after pScrn->display has been set because
1191      * xf86SetWeight references it.
1192      */
1193     if (pScrn->depth > 8) {
1194         /* The defaults are OK for us */
1195         rgb zeros = {0, 0, 0};
1196
1197         if (!xf86SetWeight(pScrn, zeros, zeros)) {
1198             xf86FreeInt10(pNv->pInt);
1199             return FALSE;
1200         }
1201     }
1202
1203     if (!xf86SetDefaultVisual(pScrn, -1)) {
1204         xf86FreeInt10(pNv->pInt);
1205         return FALSE;
1206     } else {
1207         /* We don't currently support DirectColor at > 8bpp */
1208         if (pScrn->depth > 8 && (pScrn->defaultVisual != TrueColor)) {
1209             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
1210                        " (%s) is not supported at depth %d\n",
1211                        xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
1212             xf86FreeInt10(pNv->pInt);
1213             return FALSE;
1214         }
1215     }
1216
1217     /* The vgahw module should be loaded here when needed */
1218     if (!xf86LoadSubModule(pScrn, "vgahw")) {
1219         xf86FreeInt10(pNv->pInt);
1220         return FALSE;
1221     }
1222     
1223     xf86LoaderReqSymLists(vgahwSymbols, NULL);
1224
1225     /*
1226      * Allocate a vgaHWRec
1227      */
1228     if (!vgaHWGetHWRec(pScrn)) {
1229         xf86FreeInt10(pNv->pInt);
1230         return FALSE;
1231     }
1232     
1233     /* We use a programmable clock */
1234     pScrn->progClock = TRUE;
1235
1236     /* Collect all of the relevant option flags (fill in pScrn->options) */
1237     xf86CollectOptions(pScrn, NULL);
1238
1239     /* Process the options */
1240     if (!(pNv->Options = xalloc(sizeof(NVOptions))))
1241         return FALSE;
1242     memcpy(pNv->Options, NVOptions, sizeof(NVOptions));
1243     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options);
1244
1245     /* Set the bits per RGB for 8bpp mode */
1246     if (pScrn->depth == 8)
1247         pScrn->rgbBits = 8;
1248
1249     from = X_DEFAULT;
1250     pNv->HWCursor = TRUE;
1251     /*
1252      * The preferred method is to use the "hw cursor" option as a tri-state
1253      * option, with the default set above.
1254      */
1255     if (xf86GetOptValBool(pNv->Options, OPTION_HW_CURSOR, &pNv->HWCursor)) {
1256         from = X_CONFIG;
1257     }
1258     /* For compatibility, accept this too (as an override) */
1259     if (xf86ReturnOptValBool(pNv->Options, OPTION_SW_CURSOR, FALSE)) {
1260         from = X_CONFIG;
1261         pNv->HWCursor = FALSE;
1262     }
1263     xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
1264                 pNv->HWCursor ? "HW" : "SW");
1265
1266     pNv->FpScale = TRUE;
1267     if (xf86GetOptValBool(pNv->Options, OPTION_FP_SCALE, &pNv->FpScale)) {
1268         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Flat panel scaling %s\n",
1269                    pNv->FpScale ? "on" : "off");
1270     }
1271     if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) {
1272         pNv->NoAccel = TRUE;
1273         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
1274     }
1275     if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) {
1276         pNv->ShadowFB = TRUE;
1277         pNv->NoAccel = TRUE;
1278         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1279                 "Using \"Shadow Framebuffer\" - acceleration disabled\n");
1280     }
1281     if (!pNv->NoAccel) {
1282         from = X_DEFAULT;
1283         pNv->useEXA = TRUE;
1284         if((s = (char *)xf86GetOptValString(pNv->Options, OPTION_ACCELMETHOD))) {
1285             if(!xf86NameCmp(s,"XAA")) {
1286                 from = X_CONFIG;
1287                 pNv->useEXA = FALSE;
1288             } else if(!xf86NameCmp(s,"EXA")) {
1289                 from = X_CONFIG;
1290                 pNv->useEXA = TRUE;
1291             }
1292         }
1293         xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration method\n", pNv->useEXA ? "EXA" : "XAA");
1294     } else {
1295         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
1296     }
1297     
1298     pNv->Rotate = 0;
1299     pNv->RandRRotation = FALSE;
1300     if ((s = xf86GetOptValString(pNv->Options, OPTION_ROTATE))) {
1301       if(!xf86NameCmp(s, "CW")) {
1302         pNv->ShadowFB = TRUE;
1303         pNv->NoAccel = TRUE;
1304         pNv->HWCursor = FALSE;
1305         pNv->Rotate = 1;
1306         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1307                 "Rotating screen clockwise - acceleration disabled\n");
1308       } else
1309       if(!xf86NameCmp(s, "CCW")) {
1310         pNv->ShadowFB = TRUE;
1311         pNv->NoAccel = TRUE;
1312         pNv->HWCursor = FALSE;
1313         pNv->Rotate = -1;
1314         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1315                 "Rotating screen counter clockwise - acceleration disabled\n");
1316       } else
1317       if(!xf86NameCmp(s, "RandR")) {
1318 #ifdef RANDR
1319         pNv->ShadowFB = TRUE;
1320         pNv->NoAccel = TRUE;
1321         pNv->HWCursor = FALSE;
1322         pNv->RandRRotation = TRUE;
1323         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1324                 "Using RandR rotation - acceleration disabled\n");
1325 #else
1326         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1327                 "This driver was not compiled with support for the Resize and "
1328                 "Rotate extension.  Cannot honor 'Option \"Rotate\" "
1329                 "\"RandR\"'.\n");
1330 #endif
1331       } else {
1332         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1333                 "\"%s\" is not a valid value for Option \"Rotate\"\n", s);
1334         xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
1335                 "Valid options are \"CW\", \"CCW\", and \"RandR\"\n");
1336       }
1337     }
1338
1339     if(xf86GetOptValInteger(pNv->Options, OPTION_VIDEO_KEY, &(pNv->videoKey))) {
1340         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
1341                                 pNv->videoKey);
1342     } else {
1343         pNv->videoKey =  (1 << pScrn->offset.red) | 
1344                           (1 << pScrn->offset.green) |
1345         (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue); 
1346     }
1347
1348     if (xf86GetOptValBool(pNv->Options, OPTION_FLAT_PANEL, &(pNv->FlatPanel))) {
1349         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "forcing %s usage\n",
1350                    pNv->FlatPanel ? "DFP" : "CRTC");
1351     } else {
1352         pNv->FlatPanel = -1;   /* autodetect later */
1353     }
1354
1355     pNv->FPDither = FALSE;
1356     if (xf86GetOptValBool(pNv->Options, OPTION_FP_DITHER, &(pNv->FPDither))) 
1357         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "enabling flat panel dither\n");
1358
1359     if (xf86GetOptValInteger(pNv->Options, OPTION_CRTC_NUMBER,
1360                              &pNv->CRTCnumber)) 
1361     {
1362         if((pNv->CRTCnumber < 0) || (pNv->CRTCnumber > 1)) {
1363            pNv->CRTCnumber = -1;
1364            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1365                       "Invalid CRTC number.  Must be 0 or 1\n");
1366         }
1367     } else {
1368         pNv->CRTCnumber = -1; /* autodetect later */
1369     }
1370
1371
1372     if (xf86GetOptValInteger(pNv->Options, OPTION_FP_TWEAK, 
1373                              &pNv->PanelTweak))
1374     {
1375         pNv->usePanelTweak = TRUE;
1376     } else {
1377         pNv->usePanelTweak = FALSE;
1378     }
1379     
1380     if (pNv->pEnt->device->MemBase != 0) {
1381         /* Require that the config file value matches one of the PCI values. */
1382         if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->MemBase)) {
1383             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1384                 "MemBase 0x%08lX doesn't match any PCI base register.\n",
1385                 pNv->pEnt->device->MemBase);
1386             xf86FreeInt10(pNv->pInt);
1387             NVFreeRec(pScrn);
1388             return FALSE;
1389         }
1390         pNv->VRAMPhysical = pNv->pEnt->device->MemBase;
1391         from = X_CONFIG;
1392     } else {
1393         if (pNv->PciInfo->memBase[1] != 0) {
1394             pNv->VRAMPhysical = pNv->PciInfo->memBase[1] & 0xff800000;
1395             from = X_PROBED;
1396         } else {
1397             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1398                            "No valid FB address in PCI config space\n");
1399             xf86FreeInt10(pNv->pInt);
1400             NVFreeRec(pScrn);
1401             return FALSE;
1402         }
1403     }
1404     xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
1405                (unsigned long)pNv->VRAMPhysical);
1406
1407     if (pNv->pEnt->device->IOBase != 0) {
1408         /* Require that the config file value matches one of the PCI values. */
1409         if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->IOBase)) {
1410             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1411                 "IOBase 0x%08lX doesn't match any PCI base register.\n",
1412                 pNv->pEnt->device->IOBase);
1413             xf86FreeInt10(pNv->pInt);
1414             NVFreeRec(pScrn);
1415             return FALSE;
1416         }
1417         pNv->IOAddress = pNv->pEnt->device->IOBase;
1418         from = X_CONFIG;
1419     } else {
1420         if (pNv->PciInfo->memBase[0] != 0) {
1421             pNv->IOAddress = pNv->PciInfo->memBase[0] & 0xffffc000;
1422             from = X_PROBED;
1423         } else {
1424             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1425                         "No valid MMIO address in PCI config space\n");
1426             xf86FreeInt10(pNv->pInt);
1427             NVFreeRec(pScrn);
1428             return FALSE;
1429         }
1430     }
1431     xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
1432                (unsigned long)pNv->IOAddress);
1433      
1434     if (xf86RegisterResources(pNv->pEnt->index, NULL, ResExclusive)) {
1435         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1436                 "xf86RegisterResources() found resource conflicts\n");
1437         xf86FreeInt10(pNv->pInt);
1438         NVFreeRec(pScrn);
1439         return FALSE;
1440     }
1441
1442     switch (pNv->Chipset & 0x0ff0) {
1443     case CHIPSET_NV10:   /* GeForce 256 */
1444     case CHIPSET_NV11:   /* GeForce2 MX */
1445     case CHIPSET_NV15:   /* GeForce2 */
1446     case CHIPSET_NV17:   /* GeForce4 MX */
1447     case CHIPSET_NV18:   /* GeForce4 MX (8x AGP) */
1448     case CHIPSET_NFORCE: /* nForce */
1449     case CHIPSET_NFORCE2:/* nForce2 */
1450          pNv->Architecture =  NV_ARCH_10;
1451          break;
1452     case CHIPSET_NV20:   /* GeForce3 */
1453     case CHIPSET_NV25:   /* GeForce4 Ti */
1454     case CHIPSET_NV28:   /* GeForce4 Ti (8x AGP) */
1455          pNv->Architecture =  NV_ARCH_20;
1456          break;
1457     case CHIPSET_NV30:   /* GeForceFX 5800 */
1458     case CHIPSET_NV31:   /* GeForceFX 5600 */
1459     case CHIPSET_NV34:   /* GeForceFX 5200 */
1460     case CHIPSET_NV35:   /* GeForceFX 5900 */
1461     case CHIPSET_NV36:   /* GeForceFX 5700 */
1462          pNv->Architecture =  NV_ARCH_30;
1463          break;
1464     case CHIPSET_NV40:   /* GeForce 6800 */
1465     case CHIPSET_NV41:   /* GeForce 6800 */
1466     case 0x0120:   /* GeForce 6800 */
1467     case CHIPSET_NV43:   /* GeForce 6600 */
1468     case CHIPSET_NV44:   /* GeForce 6200 */
1469     case CHIPSET_G72:   /* GeForce 7200, 7300, 7400 */
1470     case CHIPSET_G70:   /* GeForce 7800 */
1471     case CHIPSET_NV45:   /* GeForce 6800 */
1472     case CHIPSET_NV44A:   /* GeForce 6200 */
1473     case CHIPSET_G71:   /* GeForce 7900 */
1474     case CHIPSET_G73:   /* GeForce 7600 */
1475     case CHIPSET_C51:   /* GeForce 6100 */
1476     case CHIPSET_C512: /* Geforce 6100 (nForce 4xx) */
1477          pNv->Architecture =  NV_ARCH_40;
1478          break;
1479     default:
1480          pNv->Architecture =  NV_ARCH_04;
1481          break;
1482     }
1483
1484     pNv->alphaCursor = (pNv->Architecture >= NV_ARCH_10) &&
1485                        ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10);
1486
1487     NVCommonSetup(pScrn);
1488
1489     pScrn->videoRam = pNv->RamAmountKBytes;
1490     xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kBytes\n",
1491                pScrn->videoRam);
1492         
1493         pNv->VRAMPhysicalSize = pScrn->videoRam * 1024;
1494
1495     /*
1496      * If the driver can do gamma correction, it should call xf86SetGamma()
1497      * here.
1498      */
1499
1500     {
1501         Gamma zeros = {0.0, 0.0, 0.0};
1502
1503         if (!xf86SetGamma(pScrn, zeros)) {
1504             xf86FreeInt10(pNv->pInt);
1505             return FALSE;
1506         }
1507     }
1508
1509     /*
1510      * Setup the ClockRanges, which describe what clock ranges are available,
1511      * and what sort of modes they can be used for.
1512      */
1513
1514     clockRanges = xnfcalloc(sizeof(ClockRange), 1);
1515     clockRanges->next = NULL;
1516     clockRanges->minClock = pNv->MinVClockFreqKHz;
1517     clockRanges->maxClock = pNv->MaxVClockFreqKHz;
1518     clockRanges->clockIndex = -1;               /* programmable */
1519     clockRanges->doubleScanAllowed = TRUE;
1520     if((pNv->Architecture == NV_ARCH_20) ||
1521          ((pNv->Architecture == NV_ARCH_10) && 
1522            ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10) &&
1523            ((pNv->Chipset & 0x0ff0) != CHIPSET_NV15)))
1524     {
1525        /* HW is broken */
1526        clockRanges->interlaceAllowed = FALSE;
1527     } else {
1528        clockRanges->interlaceAllowed = TRUE;
1529     }
1530
1531     if(pNv->FlatPanel == 1) {
1532        clockRanges->interlaceAllowed = FALSE;
1533        clockRanges->doubleScanAllowed = FALSE;
1534     }
1535
1536     if(pNv->Architecture < NV_ARCH_10) {
1537        max_width = (pScrn->bitsPerPixel > 16) ? 2032 : 2048;
1538        max_height = 2048;
1539     } else {
1540        max_width = (pScrn->bitsPerPixel > 16) ? 4080 : 4096;
1541        max_height = 4096;
1542     }
1543
1544     /*
1545      * xf86ValidateModes will check that the mode HTotal and VTotal values
1546      * don't exceed the chipset's limit if pScrn->maxHValue and
1547      * pScrn->maxVValue are set.  Since our NVValidMode() already takes
1548      * care of this, we don't worry about setting them here.
1549      */
1550     i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
1551                           pScrn->display->modes, clockRanges,
1552                           NULL, 256, max_width,
1553                           512, 128, max_height,
1554                           pScrn->display->virtualX,
1555                           pScrn->display->virtualY,
1556                           pNv->VRAMPhysicalSize / 2,
1557                           LOOKUP_BEST_REFRESH);
1558
1559     if (i == -1) {
1560         xf86FreeInt10(pNv->pInt);
1561         NVFreeRec(pScrn);
1562         return FALSE;
1563     }
1564
1565     /* Prune the modes marked as invalid */
1566     xf86PruneDriverModes(pScrn);
1567
1568     if (i == 0 || pScrn->modes == NULL) {
1569         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
1570         xf86FreeInt10(pNv->pInt);
1571         NVFreeRec(pScrn);
1572         return FALSE;
1573     }
1574
1575     /*
1576      * Set the CRTC parameters for all of the modes based on the type
1577      * of mode, and the chipset's interlace requirements.
1578      *
1579      * Calling this is required if the mode->Crtc* values are used by the
1580      * driver and if the driver doesn't provide code to set them.  They
1581      * are not pre-initialised at all.
1582      */
1583     xf86SetCrtcForModes(pScrn, 0);
1584
1585     /* Set the current mode to the first in the list */
1586     pScrn->currentMode = pScrn->modes;
1587
1588     /* Print the list of modes being used */
1589     xf86PrintModes(pScrn);
1590
1591     /* Set display resolution */
1592     xf86SetDpi(pScrn, 0, 0);
1593
1594
1595     /*
1596      * XXX This should be taken into account in some way in the mode valdation
1597      * section.
1598      */
1599
1600     if (xf86LoadSubModule(pScrn, "fb") == NULL) {
1601         xf86FreeInt10(pNv->pInt);
1602         NVFreeRec(pScrn);
1603         return FALSE;
1604     }
1605
1606     xf86LoaderReqSymLists(fbSymbols, NULL);
1607     
1608     /* Load XAA if needed */
1609     if (!pNv->NoAccel) {
1610         if (!xf86LoadSubModule(pScrn, pNv->useEXA ? "exa" : "xaa")) {
1611             xf86FreeInt10(pNv->pInt);
1612             NVFreeRec(pScrn);
1613             return FALSE;
1614         }
1615         xf86LoaderReqSymLists(xaaSymbols, NULL);
1616     }
1617
1618     /* Load ramdac if needed */
1619     if (pNv->HWCursor) {
1620         if (!xf86LoadSubModule(pScrn, "ramdac")) {
1621             xf86FreeInt10(pNv->pInt);
1622             NVFreeRec(pScrn);
1623             return FALSE;
1624         }
1625         xf86LoaderReqSymLists(ramdacSymbols, NULL);
1626     }
1627
1628     /* Load shadowfb if needed */
1629     if (pNv->ShadowFB) {
1630         if (!xf86LoadSubModule(pScrn, "shadowfb")) {
1631             xf86FreeInt10(pNv->pInt);
1632             NVFreeRec(pScrn);
1633             return FALSE;
1634         }
1635         xf86LoaderReqSymLists(shadowSymbols, NULL);
1636     }
1637
1638     pNv->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
1639     pNv->CurrentLayout.depth = pScrn->depth;
1640     pNv->CurrentLayout.displayWidth = pScrn->displayWidth;
1641     pNv->CurrentLayout.weight.red = pScrn->weight.red;
1642     pNv->CurrentLayout.weight.green = pScrn->weight.green;
1643     pNv->CurrentLayout.weight.blue = pScrn->weight.blue;
1644     pNv->CurrentLayout.mode = pScrn->currentMode;
1645
1646     xf86FreeInt10(pNv->pInt);
1647
1648     pNv->pInt = NULL;
1649     return TRUE;
1650 }
1651
1652
1653 /*
1654  * Map the framebuffer and MMIO memory.
1655  */
1656
1657 static Bool
1658 NVMapMem(ScrnInfoPtr pScrn)
1659 {
1660         NVPtr pNv = NVPTR(pScrn);
1661
1662         pNv->FB = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, pNv->VRAMPhysicalSize/2);
1663         if (!pNv->FB) {
1664                 ErrorF("Failed to allocate memory for framebuffer!\n");
1665                 return FALSE;
1666         }
1667         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1668                         "Allocated %dMiB VRAM for framebuffer + offscreen pixmaps\n",
1669                         pNv->FB->size >> 20
1670                         );
1671
1672         pNv->Cursor = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, 64*1024);
1673         if (!pNv->Cursor) {
1674                 ErrorF("Failed to allocate memory for hardware cursor\n");
1675                 return FALSE;
1676         }
1677
1678         pNv->ScratchBuffer = NVAllocateMemory(pNv, NOUVEAU_MEM_FB,
1679                         pNv->Architecture <NV_ARCH_10 ? 8192 : 16384);
1680         if (!pNv->ScratchBuffer) {
1681                 ErrorF("Failed to allocate memory for scratch buffer\n");
1682                 return FALSE;
1683         }
1684
1685     return TRUE;
1686 }
1687
1688 /*
1689  * Unmap the framebuffer and MMIO memory.
1690  */
1691
1692 static Bool
1693 NVUnmapMem(ScrnInfoPtr pScrn)
1694 {
1695         NVPtr pNv = NVPTR(pScrn);
1696
1697         NVFreeMemory(pNv, pNv->FB);
1698         NVFreeMemory(pNv, pNv->ScratchBuffer);
1699         NVFreeMemory(pNv, pNv->Cursor);
1700
1701     return TRUE;
1702 }
1703
1704
1705 /*
1706  * Initialise a new mode. 
1707  */
1708
1709 static Bool
1710 NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1711 {
1712     vgaHWPtr hwp = VGAHWPTR(pScrn);
1713     vgaRegPtr vgaReg;
1714     NVPtr pNv = NVPTR(pScrn);
1715     NVRegPtr nvReg;
1716
1717     /* Initialise the ModeReg values */
1718     if (!vgaHWInit(pScrn, mode))
1719         return FALSE;
1720     pScrn->vtSema = TRUE;
1721
1722     vgaReg = &hwp->ModeReg;
1723     nvReg = &pNv->ModeReg;
1724
1725     if(!NVDACInit(pScrn, mode))
1726         return FALSE;
1727
1728     NVLockUnlock(pNv, 0);
1729     if(pNv->twoHeads) {
1730         nvWriteVGA(pNv, 0x44, nvReg->crtcOwner);
1731         NVLockUnlock(pNv, 0);
1732     }
1733
1734     /* Program the registers */
1735     vgaHWProtect(pScrn, TRUE);
1736
1737     NVDACRestore(pScrn, vgaReg, nvReg, FALSE);
1738
1739 #if X_BYTE_ORDER == X_BIG_ENDIAN
1740     /* turn on LFB swapping */
1741     {
1742         unsigned char tmp;
1743
1744         tmp = nvReadVGA(pNv, 0x46);
1745         tmp |= (1 << 7);
1746         nvWriteVGA(pNv, 0x46, tmp);
1747     }
1748 #endif
1749
1750     NVResetGraphics(pScrn);
1751
1752     vgaHWProtect(pScrn, FALSE);
1753
1754     pNv->CurrentLayout.mode = mode;
1755
1756     return TRUE;
1757 }
1758
1759 /*
1760  * Restore the initial (text) mode.
1761  */
1762 static void 
1763 NVRestore(ScrnInfoPtr pScrn)
1764 {
1765     vgaHWPtr hwp = VGAHWPTR(pScrn);
1766     vgaRegPtr vgaReg = &hwp->SavedReg;
1767     NVPtr pNv = NVPTR(pScrn);
1768     NVRegPtr nvReg = &pNv->SavedReg;
1769
1770     NVLockUnlock(pNv, 0);
1771
1772     if(pNv->twoHeads) {
1773         nvWriteVGA(pNv, 0x44, pNv->CRTCnumber * 0x3);
1774         NVLockUnlock(pNv, 0);
1775     }
1776
1777     /* Only restore text mode fonts/text for the primary card */
1778     vgaHWProtect(pScrn, TRUE);
1779     NVDACRestore(pScrn, vgaReg, nvReg, pNv->Primary);
1780     if(pNv->twoHeads) {
1781         nvWriteVGA(pNv, 0x44, pNv->vtOWNER);
1782     }
1783     vgaHWProtect(pScrn, FALSE);
1784 }
1785
1786 static void NVBacklightEnable(NVPtr pNv,  Bool on)
1787 {
1788     /* This is done differently on each laptop.  Here we
1789        define the ones we know for sure. */
1790
1791 #if defined(__powerpc__)
1792     if((pNv->Chipset == 0x10DE0179) || 
1793        (pNv->Chipset == 0x10DE0189) || 
1794        (pNv->Chipset == 0x10DE0329))
1795     {
1796        /* NV17,18,34 Apple iMac, iBook, PowerBook */
1797       CARD32 tmp_pmc, tmp_pcrt;
1798       tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
1799       tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
1800       if(on) {
1801           tmp_pmc |= (1 << 31);
1802           tmp_pcrt |= 0x1;
1803       }
1804       nvWriteMC(pNv, 0x10F0, tmp_pmc);
1805       nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
1806     }
1807 #endif
1808     
1809     if(pNv->LVDS) {
1810        if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11)) {
1811            nvWriteMC(pNv, 0x130C, on ? 3 : 7);
1812        }
1813     } else {
1814        CARD32 fpcontrol;
1815
1816        fpcontrol = nvReadCurRAMDAC(pNv, 0x848) & 0xCfffffCC;
1817
1818        /* cut the TMDS output */
1819        if(on) fpcontrol |= pNv->fpSyncs;
1820        else fpcontrol |= 0x20000022;
1821
1822        nvWriteCurRAMDAC(pNv, 0x0848, fpcontrol);
1823     }
1824 }
1825
1826 static void
1827 NVDPMSSetLCD(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
1828 {
1829   NVPtr pNv = NVPTR(pScrn);
1830
1831   if (!pScrn->vtSema) return;
1832
1833   vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
1834
1835   switch (PowerManagementMode) {
1836   case DPMSModeStandby:  /* HSync: Off, VSync: On */
1837   case DPMSModeSuspend:  /* HSync: On, VSync: Off */
1838   case DPMSModeOff:      /* HSync: Off, VSync: Off */
1839     NVBacklightEnable(pNv, 0);
1840     break;
1841   case DPMSModeOn:       /* HSync: On, VSync: On */
1842     NVBacklightEnable(pNv, 1);
1843   default:
1844     break;
1845   }
1846 }
1847
1848
1849 static void
1850 NVDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
1851 {
1852   unsigned char crtc1A;
1853   vgaHWPtr hwp = VGAHWPTR(pScrn);
1854
1855   if (!pScrn->vtSema) return;
1856
1857   crtc1A = hwp->readCrtc(hwp, 0x1A) & ~0xC0;
1858
1859   switch (PowerManagementMode) {
1860   case DPMSModeStandby:  /* HSync: Off, VSync: On */
1861     crtc1A |= 0x80;
1862     break;
1863   case DPMSModeSuspend:  /* HSync: On, VSync: Off */
1864     crtc1A |= 0x40;
1865     break;
1866   case DPMSModeOff:      /* HSync: Off, VSync: Off */
1867     crtc1A |= 0xC0;
1868     break;
1869   case DPMSModeOn:       /* HSync: On, VSync: On */
1870   default:
1871     break;
1872   }
1873
1874   /* vgaHWDPMSSet will merely cut the dac output */
1875   vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
1876
1877   hwp->writeCrtc(hwp, 0x1A, crtc1A);
1878 }
1879
1880
1881 /* Mandatory */
1882
1883 /* This gets called at the start of each server generation */
1884
1885 static Bool
1886 NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
1887 {
1888     ScrnInfoPtr pScrn;
1889     vgaHWPtr hwp;
1890     NVPtr pNv;
1891     int ret;
1892     VisualPtr visual;
1893     unsigned char *FBStart;
1894     int width, height, displayWidth, offscreenHeight, shadowHeight;
1895     BoxRec AvailFBArea;
1896
1897     /* 
1898      * First get the ScrnInfoRec
1899      */
1900     pScrn = xf86Screens[pScreen->myNum];
1901
1902     hwp = VGAHWPTR(pScrn);
1903     pNv = NVPTR(pScrn);
1904
1905     /* Map the VGA memory when the primary video */
1906     if (pNv->Primary) {
1907         hwp->MapSize = 0x10000;
1908         if (!vgaHWMapMem(pScrn))
1909             return FALSE;
1910     }
1911
1912         /* Init DRM - Alloc FIFO, setup graphics objects */
1913         if (!NVInitDma(pScrn))
1914                 return FALSE;
1915
1916     /* Allocate and map memory areas we need */
1917     if (!NVMapMem(pScrn)) {
1918         return FALSE;
1919     }
1920
1921         /* Save the current state */
1922         NVSave(pScrn);
1923         /* Initialise the first mode */
1924         if (!NVModeInit(pScrn, pScrn->currentMode)) {
1925             return FALSE;
1926     }
1927
1928     /* Darken the screen for aesthetic reasons and set the viewport */
1929     NVSaveScreen(pScreen, SCREEN_SAVER_ON);
1930     pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
1931
1932     /*
1933      * The next step is to setup the screen's visuals, and initialise the
1934      * framebuffer code.  In cases where the framebuffer's default
1935      * choices for things like visual layouts and bits per RGB are OK,
1936      * this may be as simple as calling the framebuffer's ScreenInit()
1937      * function.  If not, the visuals will need to be setup before calling
1938      * a fb ScreenInit() function and fixed up after.
1939      *
1940      * For most PC hardware at depths >= 8, the defaults that fb uses
1941      * are not appropriate.  In this driver, we fixup the visuals after.
1942      */
1943
1944     /*
1945      * Reset the visual list.
1946      */
1947     miClearVisualTypes();
1948
1949     /* Setup the visuals we support. */
1950
1951     if (!miSetVisualTypes(pScrn->depth, 
1952                           miGetDefaultVisualMask(pScrn->depth), 8,
1953                           pScrn->defaultVisual))
1954           return FALSE;
1955     if (!miSetPixmapDepths ()) return FALSE;
1956
1957     /*
1958      * Call the framebuffer layer's ScreenInit function, and fill in other
1959      * pScreen fields.
1960      */
1961
1962     width = pScrn->virtualX;
1963     height = pScrn->virtualY;
1964     displayWidth = pScrn->displayWidth;
1965
1966
1967     if(pNv->Rotate) {
1968         height = pScrn->virtualX;
1969         width = pScrn->virtualY;
1970     }
1971
1972     /* If RandR rotation is enabled, leave enough space in the
1973      * framebuffer for us to rotate the screen dimensions without
1974      * changing the pitch.
1975      */
1976     if(pNv->RandRRotation)
1977         shadowHeight = max(width, height);
1978     else
1979         shadowHeight = height;
1980
1981     if(pNv->ShadowFB) {
1982         pNv->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
1983         pNv->ShadowPtr = xalloc(pNv->ShadowPitch * shadowHeight);
1984         displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3);
1985         FBStart = pNv->ShadowPtr;
1986     } else {
1987         pNv->ShadowPtr = NULL;
1988         FBStart = pNv->FB->map;
1989     }
1990
1991     switch (pScrn->bitsPerPixel) {
1992         case 8:
1993         case 16:
1994         case 32:
1995             ret = fbScreenInit(pScreen, FBStart, width, height,
1996                                pScrn->xDpi, pScrn->yDpi,
1997                                displayWidth, pScrn->bitsPerPixel);
1998             break;
1999         default:
2000             xf86DrvMsg(scrnIndex, X_ERROR,
2001                        "Internal error: invalid bpp (%d) in NVScreenInit\n",
2002                        pScrn->bitsPerPixel);
2003             ret = FALSE;
2004             break;
2005     }
2006     if (!ret)
2007         return FALSE;
2008
2009     if (pScrn->bitsPerPixel > 8) {
2010         /* Fixup RGB ordering */
2011         visual = pScreen->visuals + pScreen->numVisuals;
2012         while (--visual >= pScreen->visuals) {
2013             if ((visual->class | DynamicClass) == DirectColor) {
2014                 visual->offsetRed = pScrn->offset.red;
2015                 visual->offsetGreen = pScrn->offset.green;
2016                 visual->offsetBlue = pScrn->offset.blue;
2017                 visual->redMask = pScrn->mask.red;
2018                 visual->greenMask = pScrn->mask.green;
2019                 visual->blueMask = pScrn->mask.blue;
2020             }
2021         }
2022     }
2023
2024     fbPictureInit (pScreen, 0, 0);
2025     
2026     xf86SetBlackWhitePixels(pScreen);
2027
2028     offscreenHeight = pNv->FB->size /
2029                      (pScrn->displayWidth * pScrn->bitsPerPixel >> 3);
2030     if(offscreenHeight > 32767)
2031         offscreenHeight = 32767;
2032
2033     if (!pNv->useEXA) {
2034     AvailFBArea.x1 = 0;
2035     AvailFBArea.y1 = 0;
2036     AvailFBArea.x2 = pScrn->displayWidth;
2037     AvailFBArea.y2 = offscreenHeight;
2038     xf86InitFBManager(pScreen, &AvailFBArea);
2039     }
2040     
2041     if (!pNv->NoAccel) {
2042         if (pNv->useEXA)
2043             NVExaInit(pScreen);
2044         else /* XAA */
2045             NVXaaInit(pScreen);
2046     }
2047     NVResetGraphics(pScrn);
2048     
2049     miInitializeBackingStore(pScreen);
2050     xf86SetBackingStore(pScreen);
2051     xf86SetSilkenMouse(pScreen);
2052
2053     /* Initialize software cursor.  
2054         Must precede creation of the default colormap */
2055     miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
2056
2057     /* Initialize HW cursor layer. 
2058         Must follow software cursor initialization*/
2059     if (pNv->HWCursor) { 
2060         if(!NVCursorInit(pScreen))
2061             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
2062                 "Hardware cursor initialization failed\n");
2063     }
2064
2065     /* Initialise default colourmap */
2066     if (!miCreateDefColormap(pScreen))
2067         return FALSE;
2068
2069     /* Initialize colormap layer.  
2070         Must follow initialization of the default colormap */
2071     if(!xf86HandleColormaps(pScreen, 256, 8, NVDACLoadPalette,
2072         NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
2073         return FALSE;
2074
2075     if(pNv->ShadowFB) {
2076         RefreshAreaFuncPtr refreshArea = NVRefreshArea;
2077
2078         if(pNv->Rotate || pNv->RandRRotation) {
2079            pNv->PointerMoved = pScrn->PointerMoved;
2080            if(pNv->Rotate)
2081                pScrn->PointerMoved = NVPointerMoved;
2082
2083            switch(pScrn->bitsPerPixel) {
2084                case 8:  refreshArea = NVRefreshArea8;   break;
2085                case 16: refreshArea = NVRefreshArea16;  break;
2086                case 32: refreshArea = NVRefreshArea32;  break;
2087            }
2088            if(!pNv->RandRRotation) {
2089                xf86DisableRandR();
2090                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2091                           "Driver rotation enabled, RandR disabled\n");
2092            }
2093         }
2094
2095         ShadowFBInit(pScreen, refreshArea);
2096     }
2097
2098     if(pNv->FlatPanel)
2099        xf86DPMSInit(pScreen, NVDPMSSetLCD, 0);
2100     else
2101        xf86DPMSInit(pScreen, NVDPMSSet, 0);
2102     
2103     pScrn->memPhysBase = pNv->VRAMPhysical;
2104     pScrn->fbOffset = 0;
2105
2106     if(pNv->Rotate == 0 && !pNv->RandRRotation)
2107        NVInitVideo(pScreen);
2108
2109     pScreen->SaveScreen = NVSaveScreen;
2110
2111     /* Wrap the current CloseScreen function */
2112     pNv->CloseScreen = pScreen->CloseScreen;
2113     pScreen->CloseScreen = NVCloseScreen;
2114
2115     pNv->BlockHandler = pScreen->BlockHandler;
2116     pScreen->BlockHandler = NVBlockHandler;
2117
2118 #ifdef RANDR
2119     /* Install our DriverFunc.  We have to do it this way instead of using the
2120      * HaveDriverFuncs argument to xf86AddDriver, because InitOutput clobbers
2121      * pScrn->DriverFunc */
2122     pScrn->DriverFunc = NVDriverFunc;
2123 #endif
2124
2125     /* Report any unused options (only for the first generation) */
2126     if (serverGeneration == 1) {
2127         xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
2128     }
2129     return TRUE;
2130 }
2131
2132 static Bool
2133 NVSaveScreen(ScreenPtr pScreen, int mode)
2134 {
2135     return vgaHWSaveScreen(pScreen, mode);
2136 }
2137
2138 static void
2139 NVSave(ScrnInfoPtr pScrn)
2140 {
2141     NVPtr pNv = NVPTR(pScrn);
2142     NVRegPtr nvReg = &pNv->SavedReg;
2143     vgaHWPtr pVga = VGAHWPTR(pScrn);
2144     vgaRegPtr vgaReg = &pVga->SavedReg;
2145
2146     NVLockUnlock(pNv, 0);
2147     if(pNv->twoHeads) {
2148         nvWriteVGA(pNv, 0x44, pNv->CRTCnumber * 0x3);
2149         NVLockUnlock(pNv, 0);
2150     }
2151
2152     NVDACSave(pScrn, vgaReg, nvReg, pNv->Primary);
2153 }
2154
2155 #ifdef RANDR
2156 static Bool
2157 NVRandRGetInfo(ScrnInfoPtr pScrn, Rotation *rotations)
2158 {
2159     NVPtr pNv = NVPTR(pScrn);
2160
2161     if(pNv->RandRRotation)
2162        *rotations = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_270;
2163     else
2164        *rotations = RR_Rotate_0;
2165
2166     return TRUE;
2167 }
2168
2169 static Bool
2170 NVRandRSetConfig(ScrnInfoPtr pScrn, xorgRRConfig *config)
2171 {
2172     NVPtr pNv = NVPTR(pScrn);
2173
2174     switch(config->rotation) {
2175         case RR_Rotate_0:
2176             pNv->Rotate = 0;
2177             pScrn->PointerMoved = pNv->PointerMoved;
2178             break;
2179
2180         case RR_Rotate_90:
2181             pNv->Rotate = -1;
2182             pScrn->PointerMoved = NVPointerMoved;
2183             break;
2184
2185         case RR_Rotate_270:
2186             pNv->Rotate = 1;
2187             pScrn->PointerMoved = NVPointerMoved;
2188             break;
2189
2190         default:
2191             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2192                     "Unexpected rotation in NVRandRSetConfig!\n");
2193             pNv->Rotate = 0;
2194             pScrn->PointerMoved = pNv->PointerMoved;
2195             return FALSE;
2196     }
2197
2198     return TRUE;
2199 }
2200
2201 static Bool
2202 NVDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer data)
2203 {
2204     switch(op) {
2205        case RR_GET_INFO:
2206           return NVRandRGetInfo(pScrn, (Rotation*)data);
2207        case RR_SET_CONFIG:
2208           return NVRandRSetConfig(pScrn, (xorgRRConfig*)data);
2209        default:
2210           return FALSE;
2211     }
2212
2213     return FALSE;
2214 }
2215 #endif