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