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