randr12: Remove preferred_crtc, since it's probably incorrect.
[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_EXA_PIXMAPS
1708         if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
1709                            0, pNv->VRAMPhysicalSize / 2, &pNv->FB)) {
1710                 ErrorF("Failed to allocate memory for framebuffer!\n");
1711                 return FALSE;
1712         }
1713         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1714                    "Allocated %dMiB VRAM for framebuffer + offscreen pixmaps\n",
1715                    (unsigned int)(pNv->FB->size >> 20));
1716 #endif
1717
1718
1719         if (pNv->AGPSize) {
1720                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1721                            "AGPGART: %dMiB available\n",
1722                            (unsigned int)(pNv->AGPSize >> 20));
1723                 if (pNv->AGPSize > (16*1024*1024))
1724                         gart_scratch_size = 16*1024*1024;
1725                 else
1726                         gart_scratch_size = pNv->AGPSize;
1727         } else {
1728                 gart_scratch_size = (4 << 20) - (1 << 18) ;
1729                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1730                            "GART: PCI DMA - using %dKiB\n",
1731                            gart_scratch_size >> 10);
1732         }
1733
1734 #ifndef __powerpc__
1735         if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_GART | NOUVEAU_BO_PIN, 0,
1736                            gart_scratch_size, &pNv->GART)) {
1737                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1738                            "Unable to allocate GART memory\n");
1739         }
1740 #endif
1741         if (pNv->GART) {
1742                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1743                            "GART: Allocated %dMiB as a scratch buffer\n",
1744                            (unsigned int)(pNv->GART->size >> 20));
1745         }
1746
1747         if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN, 0,
1748                            64 * 1024, &pNv->Cursor)) {
1749                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1750                            "Failed to allocate memory for hardware cursor\n");
1751                 return FALSE;
1752         }
1753
1754         if (pNv->Architecture >= NV_ARCH_50) {
1755                 if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
1756                                    0, 0x1000, &pNv->CLUT)) {
1757                         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1758                                    "Failed to allocate memory for CLUT\n");
1759                         return FALSE;
1760                 }
1761         }
1762
1763         if ((pNv->FB && nouveau_bo_map(pNv->FB, NOUVEAU_BO_RDWR)) ||
1764             (pNv->GART && nouveau_bo_map(pNv->GART, NOUVEAU_BO_RDWR)) ||
1765             (pNv->CLUT && nouveau_bo_map(pNv->CLUT, NOUVEAU_BO_RDWR)) ||
1766             nouveau_bo_map(pNv->Cursor, NOUVEAU_BO_RDWR)) {
1767                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1768                            "Failed to map pinned buffers\n");
1769                 return FALSE;
1770         }
1771
1772         return TRUE;
1773 }
1774
1775 /*
1776  * Unmap the framebuffer and MMIO memory.
1777  */
1778
1779 static Bool
1780 NVUnmapMem(ScrnInfoPtr pScrn)
1781 {
1782         NVPtr pNv = NVPTR(pScrn);
1783
1784         nouveau_bo_del(&pNv->FB);
1785         nouveau_bo_del(&pNv->GART);
1786         nouveau_bo_del(&pNv->Cursor);
1787         nouveau_bo_del(&pNv->CLUT);
1788
1789         return TRUE;
1790 }
1791
1792
1793 /*
1794  * Initialise a new mode. 
1795  */
1796
1797 static Bool
1798 NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1799 {
1800     vgaHWPtr hwp = VGAHWPTR(pScrn);
1801     vgaRegPtr vgaReg;
1802     NVPtr pNv = NVPTR(pScrn);
1803     NVRegPtr nvReg;
1804
1805     /* Initialise the ModeReg values */
1806     if (!vgaHWInit(pScrn, mode))
1807         return FALSE;
1808     pScrn->vtSema = TRUE;
1809
1810     vgaReg = &hwp->ModeReg;
1811     nvReg = &pNv->ModeReg;
1812
1813     if(!NVDACInit(pScrn, mode))
1814         return FALSE;
1815
1816     NVLockUnlock(pNv, 0);
1817     if(pNv->twoHeads) {
1818         nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, nvReg->crtcOwner);
1819         NVLockUnlock(pNv, 0);
1820     }
1821
1822     /* Program the registers */
1823     vgaHWProtect(pScrn, TRUE);
1824
1825     NVDACRestore(pScrn, vgaReg, nvReg, FALSE);
1826
1827 #if X_BYTE_ORDER == X_BIG_ENDIAN
1828     /* turn on LFB swapping */
1829     {
1830         unsigned char tmp;
1831
1832         tmp = nvReadVGA(pNv, NV_VGA_CRTCX_SWAPPING);
1833         tmp |= (1 << 7);
1834         nvWriteVGA(pNv, NV_VGA_CRTCX_SWAPPING, tmp);
1835     }
1836 #endif
1837
1838     if (!pNv->NoAccel)
1839             NVResetGraphics(pScrn);
1840
1841     vgaHWProtect(pScrn, FALSE);
1842
1843     pNv->CurrentLayout.mode = mode;
1844
1845     return TRUE;
1846 }
1847
1848 /*
1849  * Restore the initial (text) mode.
1850  */
1851 static void 
1852 NVRestore(ScrnInfoPtr pScrn)
1853 {
1854         vgaHWPtr hwp = VGAHWPTR(pScrn);
1855         vgaRegPtr vgaReg = &hwp->SavedReg;
1856         NVPtr pNv = NVPTR(pScrn);
1857         NVRegPtr nvReg = &pNv->SavedReg;
1858
1859         if (pNv->randr12_enable) {
1860                 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1861                 int i;
1862
1863                 for (i = 0; i < xf86_config->num_crtc; i++) {
1864                         NVCrtcLockUnlock(xf86_config->crtc[i], 0);
1865                 }
1866
1867                 for (i = 0; i < xf86_config->num_crtc; i++) {
1868                         xf86_config->crtc[i]->funcs->restore(xf86_config->crtc[i]);
1869                 }
1870
1871                 for (i = 0; i < xf86_config->num_output; i++) {
1872                         xf86_config->output[i]->funcs->restore(xf86_config->
1873                                                                output[i]);
1874                 }
1875
1876                 for (i = 0; i < xf86_config->num_crtc; i++) {
1877                         NVCrtcLockUnlock(xf86_config->crtc[i], 1);
1878                 }
1879         } else {
1880                 NVLockUnlock(pNv, 0);
1881
1882                 if(pNv->twoHeads) {
1883                         nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->crtc_active[1] * 0x3);
1884                         NVLockUnlock(pNv, 0);
1885                 }
1886
1887                 /* Only restore text mode fonts/text for the primary card */
1888                 vgaHWProtect(pScrn, TRUE);
1889                 NVDACRestore(pScrn, vgaReg, nvReg, pNv->Primary);
1890                 if(pNv->twoHeads) {
1891                         nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->vtOWNER);
1892                 }
1893                 vgaHWProtect(pScrn, FALSE);
1894         }
1895 }
1896
1897 static void
1898 NVLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
1899               LOCO * colors, VisualPtr pVisual)
1900 {
1901         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1902         int c;
1903         int i, j, index;
1904         CARD16 lut_r[256], lut_g[256], lut_b[256];
1905
1906         for (c = 0; c < xf86_config->num_crtc; c++) {
1907                 xf86CrtcPtr crtc = xf86_config->crtc[c];
1908
1909                 if (crtc->enabled == 0)
1910                         continue;
1911
1912                 /* code borrowed from intel driver */
1913                 switch (pScrn->depth) {
1914                 case 15:
1915                         for (i = 0; i < numColors; i++) {
1916                                 index = indices[i];
1917                                 for (j = 0; j < 8; j++) {
1918                                         lut_r[index * 8 + j] = colors[index].red << 8;
1919                                         lut_g[index * 8 + j] = colors[index].green << 8;
1920                                         lut_b[index * 8 + j] = colors[index].blue << 8;
1921                                 }
1922                         }
1923                 case 16:
1924                         for (i = 0; i < numColors; i++) {
1925                                 index = indices[i];
1926
1927                                 if (i <= 31) {
1928                                         for (j = 0; j < 8; j++) {
1929                                                 lut_r[index * 8 + j] = colors[index].red << 8;
1930                                                 lut_b[index * 8 + j] = colors[index].blue << 8;
1931                                         }
1932                                 }
1933
1934                                 for (j = 0; j < 4; j++) {
1935                                         lut_g[index * 4 + j] = colors[index].green << 8;
1936                                 }
1937                         }
1938                 default:
1939                         for (i = 0; i < numColors; i++) {
1940                                 index = indices[i];
1941                                 lut_r[index] = colors[index].red << 8;
1942                                 lut_g[index] = colors[index].green << 8;
1943                                 lut_b[index] = colors[index].blue << 8;
1944                         }
1945                         break;
1946                 }
1947
1948                 /* Make the change through RandR */
1949 #ifdef RANDR_12_INTERFACE
1950                 RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
1951 #else
1952                 crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
1953 #endif
1954         }
1955 }
1956
1957 #define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
1958 #define COLOR(c) (unsigned int)(0x3fff * ((c)/255.0))
1959 static void
1960 NV50LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
1961                 LOCO * colors, VisualPtr pVisual)
1962 {
1963         NVPtr pNv = NVPTR(pScrn);
1964         int i, index;
1965         volatile struct {
1966                 unsigned short red, green, blue, unused;
1967         } *lut = (void *) pNv->CLUT->map;
1968
1969         switch (pScrn->depth) {
1970         case 15:
1971                 for (i = 0; i < numColors; i++) {
1972                         index = indices[i];
1973                         lut[DEPTH_SHIFT(index, 5)].red =
1974                             COLOR(colors[index].red);
1975                         lut[DEPTH_SHIFT(index, 5)].green =
1976                             COLOR(colors[index].green);
1977                         lut[DEPTH_SHIFT(index, 5)].blue =
1978                             COLOR(colors[index].blue);
1979                 }
1980                 break;
1981         case 16:
1982                 for (i = 0; i < numColors; i++) {
1983                         index = indices[i];
1984                         lut[DEPTH_SHIFT(index, 6)].green =
1985                             COLOR(colors[index].green);
1986                         if (index < 32) {
1987                                 lut[DEPTH_SHIFT(index, 5)].red =
1988                                     COLOR(colors[index].red);
1989                                 lut[DEPTH_SHIFT(index, 5)].blue =
1990                                     COLOR(colors[index].blue);
1991                         }
1992                 }
1993                 break;
1994         default:
1995                 for (i = 0; i < numColors; i++) {
1996                         index = indices[i];
1997                         lut[index].red = COLOR(colors[index].red);
1998                         lut[index].green = COLOR(colors[index].green);
1999                         lut[index].blue = COLOR(colors[index].blue);
2000                 }
2001                 break;
2002         }
2003 }
2004
2005
2006 static void NVBacklightEnable(NVPtr pNv,  Bool on)
2007 {
2008     /* This is done differently on each laptop.  Here we
2009        define the ones we know for sure. */
2010
2011 #if defined(__powerpc__)
2012     if((pNv->Chipset == 0x10DE0179) || 
2013        (pNv->Chipset == 0x10DE0189) || 
2014        (pNv->Chipset == 0x10DE0329))
2015     {
2016        /* NV17,18,34 Apple iMac, iBook, PowerBook */
2017       CARD32 tmp_pmc, tmp_pcrt;
2018       tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF;
2019       tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC;
2020       if(on) {
2021           tmp_pmc |= (1 << 31);
2022           tmp_pcrt |= 0x1;
2023       }
2024       nvWriteMC(pNv, 0x10F0, tmp_pmc);
2025       nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt);
2026     }
2027 #endif
2028     
2029     if(pNv->LVDS) {
2030        if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11)) {
2031            nvWriteMC(pNv, 0x130C, on ? 3 : 7);
2032        }
2033     } else {
2034        CARD32 fpcontrol;
2035
2036        fpcontrol = nvReadCurRAMDAC(pNv, 0x848) & 0xCfffffCC;
2037
2038        /* cut the TMDS output */
2039        if(on) fpcontrol |= pNv->fpSyncs;
2040        else fpcontrol |= 0x20000022;
2041
2042        nvWriteCurRAMDAC(pNv, 0x0848, fpcontrol);
2043     }
2044 }
2045
2046 static void
2047 NVDPMSSetLCD(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
2048 {
2049   NVPtr pNv = NVPTR(pScrn);
2050
2051   if (!pScrn->vtSema) return;
2052
2053   vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
2054
2055   switch (PowerManagementMode) {
2056   case DPMSModeStandby:  /* HSync: Off, VSync: On */
2057   case DPMSModeSuspend:  /* HSync: On, VSync: Off */
2058   case DPMSModeOff:      /* HSync: Off, VSync: Off */
2059     NVBacklightEnable(pNv, 0);
2060     break;
2061   case DPMSModeOn:       /* HSync: On, VSync: On */
2062     NVBacklightEnable(pNv, 1);
2063   default:
2064     break;
2065   }
2066 }
2067
2068
2069 static void
2070 NVDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
2071 {
2072   unsigned char crtc1A;
2073   vgaHWPtr hwp = VGAHWPTR(pScrn);
2074
2075   if (!pScrn->vtSema) return;
2076
2077   crtc1A = hwp->readCrtc(hwp, 0x1A) & ~0xC0;
2078
2079   switch (PowerManagementMode) {
2080   case DPMSModeStandby:  /* HSync: Off, VSync: On */
2081     crtc1A |= 0x80;
2082     break;
2083   case DPMSModeSuspend:  /* HSync: On, VSync: Off */
2084     crtc1A |= 0x40;
2085     break;
2086   case DPMSModeOff:      /* HSync: Off, VSync: Off */
2087     crtc1A |= 0xC0;
2088     break;
2089   case DPMSModeOn:       /* HSync: On, VSync: On */
2090   default:
2091     break;
2092   }
2093
2094   /* vgaHWDPMSSet will merely cut the dac output */
2095   vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
2096
2097   hwp->writeCrtc(hwp, 0x1A, crtc1A);
2098 }
2099
2100
2101 /* Mandatory */
2102
2103 /* This gets called at the start of each server generation */
2104
2105 static Bool
2106 NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
2107 {
2108     ScrnInfoPtr pScrn;
2109     vgaHWPtr hwp;
2110     NVPtr pNv;
2111     int ret;
2112     VisualPtr visual;
2113     unsigned char *FBStart;
2114     int width, height, displayWidth, shadowHeight;
2115
2116     /* 
2117      * First get the ScrnInfoRec
2118      */
2119     pScrn = xf86Screens[pScreen->myNum];
2120
2121     hwp = VGAHWPTR(pScrn);
2122     pNv = NVPTR(pScrn);
2123
2124     /* Map the VGA memory when the primary video */
2125     if (pNv->Primary) {
2126         hwp->MapSize = 0x10000;
2127         if (!vgaHWMapMem(pScrn))
2128             return FALSE;
2129     }
2130     
2131     /* First init DRI/DRM */
2132     if (!NVDRIScreenInit(pScrn))
2133         return FALSE;
2134     
2135     /* Allocate and map memory areas we need */
2136     if (!NVMapMem(pScrn))
2137         return FALSE;
2138     
2139     if (!pNv->NoAccel) {
2140         /* Init DRM - Alloc FIFO */
2141         if (!NVInitDma(pScrn))
2142             return FALSE;
2143         
2144         /* setup graphics objects */
2145         if (!NVAccelCommonInit(pScrn))
2146             return FALSE;
2147     }
2148    
2149 #if NOUVEAU_EXA_PIXMAPS
2150     if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
2151                        0, pScrn->virtualX * pScrn->virtualY *
2152                        (pScrn->bitsPerPixel >> 3), &pNv->FB)) {
2153             ErrorF("Failed to allocate memory for screen pixmap.\n");
2154             return FALSE;
2155     }
2156 #endif
2157
2158     if (!pNv->randr12_enable) {
2159         /* Save the current state */
2160         NVSave(pScrn);
2161         /* Initialise the first mode */
2162         if (!NVModeInit(pScrn, pScrn->currentMode))
2163             return FALSE;
2164
2165         /* Darken the screen for aesthetic reasons and set the viewport */
2166         
2167         NVSaveScreen(pScreen, SCREEN_SAVER_ON);
2168         pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
2169         
2170     } else {
2171         pScrn->memPhysBase = pNv->VRAMPhysical;
2172         pScrn->fbOffset = 0;
2173
2174         /* Gather some misc info before the randr stuff kicks in */
2175         pNv->misc_info.crtc_0_reg_52 = NVReadVGA0(pNv, NV_VGA_CRTCX_52);
2176         if (pNv->Architecture == NV_ARCH_40) {
2177                 pNv->misc_info.ramdac_0_reg_580 = nvReadRAMDAC(pNv, 0, NV_RAMDAC_580);
2178                 pNv->misc_info.reg_c040 = nvReadMC(pNv, 0xc040);
2179         }
2180         pNv->misc_info.ramdac_0_pllsel = nvReadRAMDAC(pNv, 0, NV_RAMDAC_PLL_SELECT);
2181         pNv->misc_info.sel_clk = nvReadRAMDAC(pNv, 0, NV_RAMDAC_SEL_CLK);
2182
2183         if (!NVEnterVT(scrnIndex, 0))
2184             return FALSE;
2185         NVSaveScreen(pScreen, SCREEN_SAVER_ON);
2186     }
2187
2188
2189     /*
2190      * The next step is to setup the screen's visuals, and initialise the
2191      * framebuffer code.  In cases where the framebuffer's default
2192      * choices for things like visual layouts and bits per RGB are OK,
2193      * this may be as simple as calling the framebuffer's ScreenInit()
2194      * function.  If not, the visuals will need to be setup before calling
2195      * a fb ScreenInit() function and fixed up after.
2196      *
2197      * For most PC hardware at depths >= 8, the defaults that fb uses
2198      * are not appropriate.  In this driver, we fixup the visuals after.
2199      */
2200
2201     /*
2202      * Reset the visual list.
2203      */
2204     miClearVisualTypes();
2205
2206     /* Setup the visuals we support. */
2207
2208     if (!miSetVisualTypes(pScrn->depth, 
2209                           miGetDefaultVisualMask(pScrn->depth), 8,
2210                           pScrn->defaultVisual))
2211           return FALSE;
2212     if (!miSetPixmapDepths ()) return FALSE;
2213
2214     /*
2215      * Call the framebuffer layer's ScreenInit function, and fill in other
2216      * pScreen fields.
2217      */
2218
2219     width = pScrn->virtualX;
2220     height = pScrn->virtualY;
2221     displayWidth = pScrn->displayWidth;
2222
2223     if(pNv->Rotate) {
2224         height = pScrn->virtualX;
2225         width = pScrn->virtualY;
2226     }
2227
2228     /* If RandR rotation is enabled, leave enough space in the
2229      * framebuffer for us to rotate the screen dimensions without
2230      * changing the pitch.
2231      */
2232     if(pNv->RandRRotation)
2233         shadowHeight = max(width, height);
2234     else
2235         shadowHeight = height;
2236
2237     if(pNv->ShadowFB) {
2238         pNv->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
2239         pNv->ShadowPtr = xalloc(pNv->ShadowPitch * shadowHeight);
2240         displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3);
2241         FBStart = pNv->ShadowPtr;
2242     } else {
2243         pNv->ShadowPtr = NULL;
2244         FBStart = pNv->FB->map;
2245     }
2246
2247     switch (pScrn->bitsPerPixel) {
2248         case 8:
2249         case 16:
2250         case 32:
2251             ret = fbScreenInit(pScreen, FBStart, width, height,
2252                                pScrn->xDpi, pScrn->yDpi,
2253                                displayWidth, pScrn->bitsPerPixel);
2254             break;
2255         default:
2256             xf86DrvMsg(scrnIndex, X_ERROR,
2257                        "Internal error: invalid bpp (%d) in NVScreenInit\n",
2258                        pScrn->bitsPerPixel);
2259             ret = FALSE;
2260             break;
2261     }
2262     if (!ret)
2263         return FALSE;
2264
2265     if (pScrn->bitsPerPixel > 8) {
2266         /* Fixup RGB ordering */
2267         visual = pScreen->visuals + pScreen->numVisuals;
2268         while (--visual >= pScreen->visuals) {
2269             if ((visual->class | DynamicClass) == DirectColor) {
2270                 visual->offsetRed = pScrn->offset.red;
2271                 visual->offsetGreen = pScrn->offset.green;
2272                 visual->offsetBlue = pScrn->offset.blue;
2273                 visual->redMask = pScrn->mask.red;
2274                 visual->greenMask = pScrn->mask.green;
2275                 visual->blueMask = pScrn->mask.blue;
2276             }
2277         }
2278     }
2279
2280     fbPictureInit (pScreen, 0, 0);
2281     
2282     xf86SetBlackWhitePixels(pScreen);
2283
2284     if (!pNv->NoAccel) {
2285             NVExaInit(pScreen);
2286             NVResetGraphics(pScrn);
2287     }
2288     
2289     miInitializeBackingStore(pScreen);
2290     xf86SetBackingStore(pScreen);
2291     xf86SetSilkenMouse(pScreen);
2292
2293     /* Finish DRI init */
2294     NVDRIFinishScreenInit(pScrn);
2295
2296     /* Initialize software cursor.  
2297         Must precede creation of the default colormap */
2298     miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
2299
2300     /* Initialize HW cursor layer. 
2301         Must follow software cursor initialization*/
2302     if (pNv->HWCursor) { 
2303         if (pNv->Architecture < NV_ARCH_50 && !pNv->randr12_enable)
2304                 ret = NVCursorInit(pScreen);
2305         else if (pNv->Architecture < NV_ARCH_50 && pNv->randr12_enable)
2306                 ret = NVCursorInitRandr12(pScreen);
2307         else
2308                 ret = NV50CursorInit(pScreen);
2309
2310         if (ret != TRUE) {
2311             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
2312                 "Hardware cursor initialization failed\n");
2313             pNv->HWCursor = FALSE;
2314         }
2315     }
2316
2317         if (pNv->randr12_enable) {
2318                 xf86DPMSInit(pScreen, xf86DPMSSet, 0);
2319
2320                 if (!xf86CrtcScreenInit(pScreen))
2321                         return FALSE;
2322
2323                 pNv->PointerMoved = pScrn->PointerMoved;
2324                 pScrn->PointerMoved = NVPointerMoved;
2325         }
2326
2327     /* Initialise default colourmap */
2328     if (!miCreateDefColormap(pScreen))
2329         return FALSE;
2330
2331     /* Initialize colormap layer.  
2332        Must follow initialization of the default colormap */
2333     if (!pNv->randr12_enable) {
2334         if(!xf86HandleColormaps(pScreen, 256, 8, NVDACLoadPalette,
2335                                 NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
2336             return FALSE;
2337     } else {
2338         if (pNv->Architecture < NV_ARCH_50) {
2339             if (!xf86HandleColormaps(pScreen, 256, 8, NVLoadPalette,
2340                                      NULL,
2341                                      CMAP_RELOAD_ON_MODE_SWITCH |
2342                                      CMAP_PALETTED_TRUECOLOR))
2343                 return FALSE;
2344         } else {
2345             if (!xf86HandleColormaps(pScreen, 256, 8, NV50LoadPalette,
2346                                      NULL, CMAP_PALETTED_TRUECOLOR))
2347                 return FALSE;
2348         }
2349     }
2350
2351     if(pNv->ShadowFB) {
2352         RefreshAreaFuncPtr refreshArea = NVRefreshArea;
2353
2354         if(pNv->Rotate || pNv->RandRRotation) {
2355            pNv->PointerMoved = pScrn->PointerMoved;
2356            if(pNv->Rotate)
2357                pScrn->PointerMoved = NVPointerMoved;
2358
2359            switch(pScrn->bitsPerPixel) {
2360                case 8:  refreshArea = NVRefreshArea8;   break;
2361                case 16: refreshArea = NVRefreshArea16;  break;
2362                case 32: refreshArea = NVRefreshArea32;  break;
2363            }
2364            if(!pNv->RandRRotation) {
2365                xf86DisableRandR();
2366                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2367                           "Driver rotation enabled, RandR disabled\n");
2368            }
2369         }
2370
2371         ShadowFBInit(pScreen, refreshArea);
2372     }
2373
2374     if (!pNv->randr12_enable) {
2375         if(pNv->FlatPanel)
2376             xf86DPMSInit(pScreen, NVDPMSSetLCD, 0);
2377         else
2378             xf86DPMSInit(pScreen, NVDPMSSet, 0);
2379     }
2380
2381     pScrn->memPhysBase = pNv->VRAMPhysical;
2382     pScrn->fbOffset = 0;
2383
2384     if(pNv->Rotate == 0 && !pNv->RandRRotation)
2385        NVInitVideo(pScreen);
2386
2387     pScreen->SaveScreen = NVSaveScreen;
2388
2389     /* Wrap the current CloseScreen function */
2390     pNv->CloseScreen = pScreen->CloseScreen;
2391     pScreen->CloseScreen = NVCloseScreen;
2392
2393     pNv->BlockHandler = pScreen->BlockHandler;
2394     pScreen->BlockHandler = NVBlockHandler;
2395
2396 #ifdef RANDR
2397     /* Install our DriverFunc.  We have to do it this way instead of using the
2398      * HaveDriverFuncs argument to xf86AddDriver, because InitOutput clobbers
2399      * pScrn->DriverFunc */
2400     if (!pNv->randr12_enable)
2401         pScrn->DriverFunc = NVDriverFunc;
2402 #endif
2403
2404     /* Report any unused options (only for the first generation) */
2405     if (serverGeneration == 1) {
2406         xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
2407     }
2408     return TRUE;
2409 }
2410
2411 static Bool
2412 NVSaveScreen(ScreenPtr pScreen, int mode)
2413 {
2414     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2415     NVPtr pNv = NVPTR(pScrn);
2416     int i;
2417     Bool on = xf86IsUnblank(mode);
2418     
2419     if (pNv->randr12_enable) {
2420         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2421         if (pScrn->vtSema && pNv->Architecture < NV_ARCH_50) {
2422             for (i = 0; i < xf86_config->num_crtc; i++) {
2423                 
2424                 if (xf86_config->crtc[i]->enabled) {
2425                     NVCrtcBlankScreen(xf86_config->crtc[i],
2426                                       on);
2427                 }
2428             }
2429             
2430         }
2431         return TRUE;
2432     }
2433
2434         return vgaHWSaveScreen(pScreen, mode);
2435 }
2436
2437 static void
2438 NVSave(ScrnInfoPtr pScrn)
2439 {
2440     NVPtr pNv = NVPTR(pScrn);
2441     NVRegPtr nvReg = &pNv->SavedReg;
2442     vgaHWPtr pVga = VGAHWPTR(pScrn);
2443     vgaRegPtr vgaReg = &pVga->SavedReg;
2444  
2445     if (pNv->randr12_enable) {
2446         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2447         int vgaflags = VGA_SR_CMAP | VGA_SR_MODE;
2448         int i;
2449
2450         for (i = 0; i < xf86_config->num_crtc; i++) {
2451                 xf86_config->crtc[i]->funcs->save(xf86_config->crtc[i]);
2452         }
2453
2454         for (i = 0; i < xf86_config->num_output; i++) {
2455                 xf86_config->output[i]->funcs->save(xf86_config->
2456                                                     output[i]);
2457         }
2458
2459         vgaHWUnlock(pVga);
2460 #ifndef __powerpc__
2461         vgaflags |= VGA_SR_FONTS;
2462 #endif
2463         vgaHWSave(pScrn, vgaReg, vgaflags);
2464     } else {
2465         NVLockUnlock(pNv, 0);
2466         if(pNv->twoHeads) {
2467             nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->crtc_active[1] * 0x3);
2468             NVLockUnlock(pNv, 0);
2469         }
2470
2471         NVDACSave(pScrn, vgaReg, nvReg, pNv->Primary);
2472     }
2473 }
2474
2475 #ifdef RANDR
2476 static Bool
2477 NVRandRGetInfo(ScrnInfoPtr pScrn, Rotation *rotations)
2478 {
2479     NVPtr pNv = NVPTR(pScrn);
2480
2481     if(pNv->RandRRotation)
2482        *rotations = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_270;
2483     else
2484        *rotations = RR_Rotate_0;
2485
2486     return TRUE;
2487 }
2488
2489 static Bool
2490 NVRandRSetConfig(ScrnInfoPtr pScrn, xorgRRConfig *config)
2491 {
2492     NVPtr pNv = NVPTR(pScrn);
2493
2494     switch(config->rotation) {
2495         case RR_Rotate_0:
2496             pNv->Rotate = 0;
2497             pScrn->PointerMoved = pNv->PointerMoved;
2498             break;
2499
2500         case RR_Rotate_90:
2501             pNv->Rotate = -1;
2502             pScrn->PointerMoved = NVPointerMoved;
2503             break;
2504
2505         case RR_Rotate_270:
2506             pNv->Rotate = 1;
2507             pScrn->PointerMoved = NVPointerMoved;
2508             break;
2509
2510         default:
2511             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2512                     "Unexpected rotation in NVRandRSetConfig!\n");
2513             pNv->Rotate = 0;
2514             pScrn->PointerMoved = pNv->PointerMoved;
2515             return FALSE;
2516     }
2517
2518     return TRUE;
2519 }
2520
2521 static Bool
2522 NVDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer data)
2523 {
2524     switch(op) {
2525        case RR_GET_INFO:
2526           return NVRandRGetInfo(pScrn, (Rotation*)data);
2527        case RR_SET_CONFIG:
2528           return NVRandRSetConfig(pScrn, (xorgRRConfig*)data);
2529        default:
2530           return FALSE;
2531     }
2532
2533     return FALSE;
2534 }
2535 #endif