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