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