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