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