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