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