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