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