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