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