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