NV50: Implement per CRTC gamma correction.
[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 Bool    NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
59 static void    NVAdjustFrame(int scrnIndex, int x, int y, int flags);
60 static void    NVFreeScreen(int scrnIndex, int flags);
61 static ModeStatus NVValidMode(int scrnIndex, DisplayModePtr mode,
62                               Bool verbose, int flags);
63 static Bool    NVDriverFunc(ScrnInfoPtr pScrnInfo, xorgDriverFuncOp op,
64                               pointer data);
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 static Bool
278 NVGetRec(ScrnInfoPtr pScrn)
279 {
280     /*
281      * Allocate an NVRec, and hook it into pScrn->driverPrivate.
282      * pScrn->driverPrivate is initialised to NULL, so we can check if
283      * the allocation has already been done.
284      */
285     if (pScrn->driverPrivate != NULL)
286         return TRUE;
287
288     pScrn->driverPrivate = xnfcalloc(sizeof(NVRec), 1);
289     /* Initialise it */
290
291     return TRUE;
292 }
293
294 static void
295 NVFreeRec(ScrnInfoPtr pScrn)
296 {
297     if (pScrn->driverPrivate == NULL)
298         return;
299     xfree(pScrn->driverPrivate);
300     pScrn->driverPrivate = NULL;
301 }
302
303
304 static pointer
305 nouveauSetup(pointer module, pointer opts, int *errmaj, int *errmin)
306 {
307         static Bool setupDone = FALSE;
308
309         /* This module should be loaded only once, but check to be sure. */
310
311         if (!setupDone) {
312                 setupDone = TRUE;
313                 /* The 1 here is needed to turn off a backwards compatibility mode */
314                 /* Otherwise NVPciProbe() is not called */
315                 xf86AddDriver(&NV, module, 1);
316
317                 /*
318                  * Modules that this driver always requires may be loaded here
319                  * by calling LoadSubModule().
320                  */
321                 /*
322                  * Tell the loader about symbols from other modules that this module
323                  * might refer to.
324                  */
325                 LoaderRefSymLists(vgahwSymbols, exaSymbols, fbSymbols,
326                                 ramdacSymbols, shadowSymbols, drmSymbols, 
327                                 i2cSymbols, ddcSymbols, vbeSymbols,
328                                 int10Symbols, NULL);
329
330                 /*
331                  * The return value must be non-NULL on success even though there
332                  * is no TearDownProc.
333                  */
334                 return (pointer)1;
335         } else {
336                 if (errmaj) *errmaj = LDR_ONCEONLY;
337                 return NULL;
338         }
339 }
340
341 static const OptionInfoRec *
342 NVAvailableOptions(int chipid, int busid)
343 {
344     return NVOptions;
345 }
346
347 /* Mandatory */
348 static void
349 NVIdentify(int flags)
350 {
351     struct NvFamily *family;
352     size_t maxLen=0;
353
354     xf86DrvMsg(0, X_INFO, NV_NAME " driver " NV_DRIVER_DATE "\n");
355     xf86DrvMsg(0, X_INFO, NV_NAME " driver for NVIDIA chipset families :\n");
356
357     /* maximum length for alignment */
358     family = NVKnownFamilies;
359     while(family->name && family->chipset)
360     {
361         maxLen = max(maxLen, strlen(family->name));
362         family++;
363     }
364
365     /* display */
366     family = NVKnownFamilies;
367     while(family->name && family->chipset)
368     {
369         size_t len = strlen(family->name);
370         xf86ErrorF("\t%s", family->name);
371         while(len<maxLen+1)
372         {
373             xf86ErrorF(" ");
374             len++;
375         }
376         xf86ErrorF("(%s)\n", family->chipset);
377         family++;
378     }
379 }
380
381
382 #ifndef XSERVER_LIBPCIACCESS
383 static Bool
384 NVGetScrnInfoRec(PciChipsets *chips, int chip)
385 {
386     ScrnInfoPtr pScrn;
387
388     pScrn = xf86ConfigPciEntity(NULL, 0, chip,
389                                 chips, NULL, NULL, NULL,
390                                 NULL, NULL);
391
392     if(!pScrn) return FALSE;
393
394     pScrn->driverVersion    = NV_VERSION;
395     pScrn->driverName       = NV_DRIVER_NAME;
396     pScrn->name             = NV_NAME;
397
398     pScrn->Probe = NVProbe;
399     pScrn->PreInit          = NVPreInit;
400     pScrn->ScreenInit       = NVScreenInit;
401     pScrn->SwitchMode       = NVSwitchMode;
402     pScrn->AdjustFrame      = NVAdjustFrame;
403     pScrn->EnterVT          = NVEnterVT;
404     pScrn->LeaveVT          = NVLeaveVT;
405     pScrn->FreeScreen       = NVFreeScreen;
406     pScrn->ValidMode        = NVValidMode;
407
408     return TRUE;
409 }
410 #endif
411
412 /* This returns architecture in hexdecimal, so NV40 is 0x40 */
413 static int NVGetArchitecture(volatile uint32_t *regs)
414 {
415         int architecture = 0;
416
417         /* We're dealing with >=NV10 */
418         if ((regs[0] & 0x0f000000) > 0 )
419                 /* Bit 27-20 contain the architecture in hex */
420                 architecture = (regs[0] & 0xff00000) >> 20;
421         /* NV04 or NV05 */
422         else if ((regs[0] & 0xff00fff0) == 0x20004000)
423                 architecture = 0x04;
424
425         return architecture;
426 }
427
428 /* Reading the pci_id from the card registers is the most reliable way */
429 static uint32_t NVGetPCIID(volatile uint32_t *regs)
430 {
431         int architecture = NVGetArchitecture(regs);
432         uint32_t pci_id;
433
434         /* Dealing with an unknown or unsupported card */
435         if (architecture == 0)
436                 return 0;
437
438         if (architecture >= 0x40)
439                 pci_id = regs[0x88000/4];
440         else
441                 pci_id = regs[0x1800/4];
442
443         /* A pci-id can be inverted, we must correct this */
444         if ((pci_id & 0xffff) == PCI_VENDOR_NVIDIA)
445                 pci_id = (PCI_VENDOR_NVIDIA << 16) | (pci_id >> 16);
446         else if ((pci_id & 0xffff) == PCI_VENDOR_NVIDIA_SGS)
447                 pci_id = (PCI_VENDOR_NVIDIA_SGS << 16) | (pci_id >> 16);
448         /* Checking endian issues */
449         else {
450                 /* PCI_VENDOR_NVIDIA = 0x10DE */
451                 if ((pci_id & (0xffff << 16)) == (0xDE10 << 16)) /* wrong endian */
452                         pci_id = (PCI_VENDOR_NVIDIA << 16) | ((pci_id << 8) & 0x0000ff00) |
453                                 ((pci_id >> 8) & 0x000000ff);
454                 /* PCI_VENDOR_NVIDIA_SGS = 0x12D2 */
455                 else if ((pci_id & (0xffff << 16)) == (0xD212 << 16)) /* wrong endian */
456                         pci_id = (PCI_VENDOR_NVIDIA_SGS << 16) | ((pci_id << 8) & 0x0000ff00) |
457                                 ((pci_id >> 8) & 0x000000ff);
458         }
459
460         return pci_id;
461 }
462
463 #ifdef XSERVER_LIBPCIACCESS
464
465 static Bool NVPciProbe (        DriverPtr               drv,
466                                 int                     entity_num,
467                                 struct pci_device       *dev,
468                                 intptr_t                match_data      )
469 {
470         ScrnInfoPtr pScrn = NULL;
471
472         volatile uint32_t *regs = NULL;
473
474         /* Temporary mapping to discover the architecture */
475         pci_device_map_range(dev, PCI_DEV_MEM_BASE(dev, 0), 0x90000, 0,
476                              (void *) &regs);
477
478         uint8_t architecture = NVGetArchitecture(regs);
479
480         CARD32 pci_id = NVGetPCIID(regs);
481
482         pci_device_unmap_range(dev, (void *) regs, 0x90000);
483
484         /* Currently NV04 up to NV98 is known. */
485         /* Using 0x9F as upper bound for some margin. */
486         if (architecture >= 0x04 && architecture <= 0x9F) {
487
488                 /* At this stage the pci_id should be ok, so we generate this
489                  * to avoid list duplication */
490                 /* AGP bridge chips need their bridge chip id to be detected */
491                 PciChipsets NVChipsets[] = {
492                         { pci_id, PCI_DEV_PCI_ID(dev), RES_SHARED_VGA },
493                         { -1, -1, RES_UNDEFINED }
494                 };
495
496                 pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, NVChipsets, 
497                                                 NULL, NULL, NULL, NULL, NULL);
498
499                 if (pScrn != NULL) {
500                         pScrn->driverVersion    = NV_VERSION;
501                         pScrn->driverName       = NV_DRIVER_NAME;
502                         pScrn->name             = NV_NAME;
503
504                         pScrn->Probe            = NULL;
505                         pScrn->PreInit          = NVPreInit;
506                         pScrn->ScreenInit       = NVScreenInit;
507                         pScrn->SwitchMode       = NVSwitchMode;
508                         pScrn->AdjustFrame      = NVAdjustFrame;
509                         pScrn->EnterVT          = NVEnterVT;
510                         pScrn->LeaveVT          = NVLeaveVT;
511                         pScrn->FreeScreen       = NVFreeScreen;
512                         pScrn->ValidMode        = NVValidMode;
513
514                         return TRUE;
515                 }
516         }
517
518         return FALSE;
519 }
520
521 #endif /* XSERVER_LIBPCIACCESS */
522
523 #define MAX_CHIPS MAXSCREENS
524
525 #ifndef XSERVER_LIBPCIACCESS
526 /* Mandatory */
527 static Bool
528 NVProbe(DriverPtr drv, int flags)
529 {
530         int i;
531         GDevPtr *devSections;
532         int *usedChips;
533         SymTabRec NVChipsets[MAX_CHIPS + 1];
534         PciChipsets NVPciChipsets[MAX_CHIPS + 1];
535         pciVideoPtr *ppPci;
536         int numDevSections;
537         int numUsed;
538         Bool foundScreen = FALSE;
539
540         if ((numDevSections = xf86MatchDevice(NV_DRIVER_NAME, &devSections)) <= 0) 
541                 return FALSE;  /* no matching device section */
542
543         if (!(ppPci = xf86GetPciVideoInfo())) 
544                 return FALSE;  /* no PCI cards found */
545
546         numUsed = 0;
547
548         /* Create the NVChipsets and NVPciChipsets from found devices */
549         while (*ppPci && (numUsed < MAX_CHIPS)) {
550                 if (((*ppPci)->vendor == PCI_VENDOR_NVIDIA_SGS) || 
551                         ((*ppPci)->vendor == PCI_VENDOR_NVIDIA)) 
552                 {
553                         volatile uint32_t *regs;
554                         uint32_t pcicmd;
555
556                         PCI_DEV_READ_LONG(*ppPci, PCI_CMD_STAT_REG, &pcicmd);
557                         /* Enable reading memory? */
558                         PCI_DEV_WRITE_LONG(*ppPci, PCI_CMD_STAT_REG, pcicmd | PCI_CMD_MEM_ENABLE);
559
560                         regs = xf86MapPciMem(-1, VIDMEM_MMIO, PCI_DEV_TAG(*ppPci), PCI_DEV_MEM_BASE(*ppPci, 0), 0x90000);
561                         int pciid = NVGetPCIID(regs);
562
563                         int architecture = NVGetArchitecture(regs);
564                         char name[25];
565                         sprintf(name, "NVIDIA NV%02X", architecture);
566                         /* NV04 upto NV98 is known. */
567                         if (architecture >= 0x04 && architecture <= 0x9F) {
568                                 NVChipsets[numUsed].token = pciid;
569                                 NVChipsets[numUsed].name = name;
570                                 NVPciChipsets[numUsed].numChipset = pciid;
571                                 /* AGP bridge chips need their bridge chip id to be detected */
572                                 NVPciChipsets[numUsed].PCIid = PCI_DEV_PCI_ID(*ppPci);
573                                 NVPciChipsets[numUsed].resList = RES_SHARED_VGA;
574                                 numUsed++;
575                         }
576                         xf86UnMapVidMem(-1, (pointer)regs, 0x90000);
577
578                         /* Reset previous state */
579                         PCI_DEV_WRITE_LONG(*ppPci, PCI_CMD_STAT_REG, pcicmd);
580                 }
581                 ppPci++;
582         }
583
584         /* terminate the list */
585         NVChipsets[numUsed].token = -1;
586         NVChipsets[numUsed].name = NULL; 
587         NVPciChipsets[numUsed].numChipset = -1;
588         NVPciChipsets[numUsed].PCIid = -1;
589         NVPciChipsets[numUsed].resList = RES_UNDEFINED;
590
591         numUsed = xf86MatchPciInstances(NV_NAME, 0, NVChipsets, NVPciChipsets,
592                                         devSections, numDevSections, drv,
593                                         &usedChips);
594
595         if (numUsed <= 0) {
596                 return FALSE;
597         }
598
599         if (flags & PROBE_DETECT) {
600                 foundScreen = TRUE;
601         } else {
602                 for (i = 0; i < numUsed; i++) {
603                         pciVideoPtr pPci;
604
605                         pPci = xf86GetPciInfoForEntity(usedChips[i]);
606                         if (NVGetScrnInfoRec(NVPciChipsets, usedChips[i])) {
607                                 foundScreen = TRUE;
608                         }
609                 }
610         }
611
612         xfree(devSections);
613         xfree(usedChips);
614
615         return foundScreen;
616 }
617 #endif /* XSERVER_LIBPCIACCESS */
618
619 Bool
620 NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
621 {
622         ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
623         NVPtr pNv = NVPTR(pScrn);
624
625         if (pNv->randr12_enable) {
626                 /* No rotation support for the moment */
627                 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
628         }
629
630         return NVModeInit(xf86Screens[scrnIndex], mode);
631 }
632
633 /*
634  * This function is used to initialize the Start Address - the first
635  * displayed location in the video memory.
636  */
637 /* Usually mandatory */
638 void 
639 NVAdjustFrame(int scrnIndex, int x, int y, int flags)
640 {
641         ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
642         NVPtr pNv = NVPTR(pScrn);
643
644         if (pNv->randr12_enable) {
645                 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
646                 xf86CrtcPtr crtc = config->output[config->compat_output]->crtc;
647
648                 if (crtc && crtc->enabled) {
649                         NVCrtcSetBase(crtc, x, y, FALSE);
650                 }
651         } else {
652                 int startAddr;
653                 startAddr = (((y*pScrn->displayWidth)+x)*(pScrn->bitsPerPixel/8));
654                 startAddr += pNv->FB->offset;
655                 NVSetStartAddress(pNv, startAddr);
656         }
657 }
658
659 static Bool
660 NV50AcquireDisplay(ScrnInfoPtr pScrn)
661 {
662         if (!NV50DispInit(pScrn))
663                 return FALSE;
664         if (!NV50CursorAcquire(pScrn))
665                 return FALSE;
666         xf86SetDesiredModes(pScrn);
667
668         return TRUE;
669 }
670
671 static Bool
672 NV50ReleaseDisplay(ScrnInfoPtr pScrn)
673 {
674         NV50CursorRelease(pScrn);
675         NV50DispShutdown(pScrn);
676         return TRUE;
677 }
678
679 /*
680  * This is called when VT switching back to the X server.  Its job is
681  * to reinitialise the video mode.
682  *
683  * We may wish to unmap video/MMIO memory too.
684  */
685
686 /* Mandatory */
687 static Bool
688 NVEnterVT(int scrnIndex, int flags)
689 {
690         ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
691         NVPtr pNv = NVPTR(pScrn);
692
693         if (pNv->randr12_enable) {
694                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVEnterVT is called.\n");
695                 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
696                 int i;
697                 pScrn->vtSema = TRUE;
698
699                 if (pNv->Architecture == NV_ARCH_50) {
700                         if (!NV50AcquireDisplay(pScrn))
701                                 return FALSE;
702                         return TRUE;
703                 }
704
705                 /* Save the current state */
706                 if (pNv->SaveGeneration != serverGeneration) {
707                         pNv->SaveGeneration = serverGeneration;
708                         NVSave(pScrn);
709                 }
710
711                 for (i = 0; i < xf86_config->num_crtc; i++) {
712                         NVCrtcLockUnlock(xf86_config->crtc[i], 0);
713                 }
714
715                 /* Reassign outputs so disabled outputs don't get stuck on the wrong crtc */
716                 for (i = 0; i < xf86_config->num_output; i++) {
717                         NVOutputPrivatePtr nv_output = xf86_config->output[i]->driver_private;
718                         if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
719                                 uint8_t tmds04 = nv_dcb_read_tmds(pNv, nv_output->dcb_entry, 0, 0x4);
720
721                                 /* Disable any crosswired tmds, to avoid picking up a signal on a disabled output */
722                                 /* Example: TMDS1 crosswired to CRTC0 (by bios) reassigned to CRTC1 in xorg, disabled. */
723                                 /* But the bios reinits it to CRTC0 when going back to VT. */
724                                 /* Because it's disabled, it doesn't get a mode set, still it picks up the signal from CRTC0 (which is another output) */
725                                 /* A legitimately crosswired output will get set properly during mode set */
726                                 if (tmds04 & 8)
727                                         nv_dcb_write_tmds(pNv, nv_output->dcb_entry, 0, 0x4, tmds04 ^ 8);
728                         }
729                 }
730
731                 if (!xf86SetDesiredModes(pScrn))
732                         return FALSE;
733         } else {
734                 if (!NVModeInit(pScrn, pScrn->currentMode))
735                         return FALSE;
736
737                 NVAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
738         }
739
740         if (pNv->overlayAdaptor && pNv->Architecture != NV_ARCH_04)
741                 NV10WriteOverlayParameters(pScrn);
742         return TRUE;
743 }
744
745 /*
746  * This is called when VT switching away from the X server.  Its job is
747  * to restore the previous (text) mode.
748  *
749  * We may wish to remap video/MMIO memory too.
750  */
751
752 /* Mandatory */
753 static void
754 NVLeaveVT(int scrnIndex, int flags)
755 {
756         ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
757         NVPtr pNv = NVPTR(pScrn);
758         if (pNv->randr12_enable)
759                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVLeaveVT is called.\n");
760
761         if (pNv->Architecture == NV_ARCH_50) {
762                 NV50ReleaseDisplay(pScrn);
763                 return;
764         }
765         NVSync(pScrn);
766         NVRestore(pScrn);
767         if (!pNv->randr12_enable)
768                 NVLockUnlock(pScrn, 1);
769 }
770
771
772
773 static void 
774 NVBlockHandler (
775         int i, 
776         pointer blockData, 
777         pointer pTimeout,
778         pointer pReadmask
779 )
780 {
781         ScreenPtr pScreen = screenInfo.screens[i];
782         ScrnInfoPtr pScrnInfo = xf86Screens[i];
783         NVPtr pNv = NVPTR(pScrnInfo);
784
785         if (!pNv->NoAccel)
786                 FIRE_RING();
787
788         pScreen->BlockHandler = pNv->BlockHandler;
789         (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
790         pScreen->BlockHandler = NVBlockHandler;
791
792         if (pNv->VideoTimerCallback) 
793                 (*pNv->VideoTimerCallback)(pScrnInfo, currentTime.milliseconds);
794
795 }
796
797
798 /*
799  * This is called at the end of each server generation.  It restores the
800  * original (text) mode.  It should also unmap the video memory, and free
801  * any per-generation data allocated by the driver.  It should finish
802  * by unwrapping and calling the saved CloseScreen function.
803  */
804
805 /* Mandatory */
806 static Bool
807 NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
808 {
809         ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
810         NVPtr pNv = NVPTR(pScrn);
811
812         if (pScrn->vtSema) {
813                 pScrn->vtSema = FALSE;
814                 if (pNv->Architecture == NV_ARCH_50) {
815                         NV50ReleaseDisplay(pScrn);
816                 } else {
817                         if (pNv->randr12_enable)
818                                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVCloseScreen is called.\n");
819                         NVSync(pScrn);
820                         NVRestore(pScrn);
821                         if (!pNv->randr12_enable)
822                                 NVLockUnlock(pScrn, 1);
823                 }
824         }
825
826         NVUnmapMem(pScrn);
827         vgaHWUnmapMem(pScrn);
828         if (pNv->CursorInfoRec)
829                 xf86DestroyCursorInfoRec(pNv->CursorInfoRec);
830         if (pNv->ShadowPtr)
831                 xfree(pNv->ShadowPtr);
832         if (pNv->overlayAdaptor)
833                 xfree(pNv->overlayAdaptor);
834         if (pNv->blitAdaptor)
835                 xfree(pNv->blitAdaptor);
836
837         pScrn->vtSema = FALSE;
838         pScreen->CloseScreen = pNv->CloseScreen;
839         pScreen->BlockHandler = pNv->BlockHandler;
840         return (*pScreen->CloseScreen)(scrnIndex, pScreen);
841 }
842
843 /* Free up any persistent data structures */
844
845 /* Optional */
846 static void
847 NVFreeScreen(int scrnIndex, int flags)
848 {
849     /*
850      * This only gets called when a screen is being deleted.  It does not
851      * get called routinely at the end of a server generation.
852      */
853     if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
854         vgaHWFreeHWRec(xf86Screens[scrnIndex]);
855     NVFreeRec(xf86Screens[scrnIndex]);
856 }
857
858
859 /* Checks if a mode is suitable for the selected chipset. */
860
861 /* Optional */
862 static ModeStatus
863 NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
864 {
865     NVPtr pNv = NVPTR(xf86Screens[scrnIndex]);
866
867     if(pNv->fpWidth && pNv->fpHeight)
868       if((pNv->fpWidth < mode->HDisplay) || (pNv->fpHeight < mode->VDisplay))
869         return (MODE_PANEL);
870
871     return (MODE_OK);
872 }
873
874 Bool NVI2CInit(ScrnInfoPtr pScrn)
875 {
876         NVPtr pNv = NVPTR(pScrn);
877
878         if (xf86LoadSubModule(pScrn, "i2c") && xf86LoadSubModule(pScrn, "ddc")) {
879                 xf86LoaderReqSymLists(i2cSymbols,NULL);
880                 xf86LoaderReqSymLists(ddcSymbols, NULL);
881
882                 /* randr-1.2 clients have their DDCs initialized elsewhere */
883                 if (!pNv->randr12_enable)
884                         return NVDACi2cInit(pScrn);
885                 return true;
886         } else
887                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
888                 "Couldn't load i2c and ddc modules.  DDC probing can't be done\n");
889         return false;
890 }
891
892 static Bool NVPreInitDRI(ScrnInfoPtr pScrn)
893 {
894         NVPtr pNv = NVPTR(pScrn);
895
896         if (!NVDRIGetVersion(pScrn))
897                 return FALSE;
898
899         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
900                 "[dri] Found DRI library version %d.%d.%d and kernel"
901                 " module version %d.%d.%d\n",
902                 pNv->pLibDRMVersion->version_major,
903                 pNv->pLibDRMVersion->version_minor,
904                 pNv->pLibDRMVersion->version_patchlevel,
905                 pNv->pKernelDRMVersion->version_major,
906                 pNv->pKernelDRMVersion->version_minor,
907                 pNv->pKernelDRMVersion->version_patchlevel);
908
909         return TRUE;
910 }
911
912 static Bool
913 nv_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
914 {
915         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_xf86crtc_resize is called with %dx%d resolution.\n", width, height);
916         pScrn->virtualX = width;
917         pScrn->virtualY = height;
918         return TRUE;
919 }
920
921 static const xf86CrtcConfigFuncsRec nv_xf86crtc_config_funcs = {
922         nv_xf86crtc_resize
923 };
924
925 /* This is taken from the haiku driver */
926 /* We must accept crtc pitch constrains */
927 /* A hardware bug on some hardware requires twice the pitch */
928 static CARD8 NVGetCRTCMask(ScrnInfoPtr pScrn, CARD8 bpp)
929 {
930         CARD8 mask = 0;
931         switch(bpp) {
932                 case 8:
933                         mask = 0xf; /* 0x7 */
934                         break;
935                 case 15:
936                         mask = 0x7; /* 0x3 */
937                         break;
938                 case 16:
939                         mask = 0x7; /* 0x3 */
940                         break;
941                 case 24:
942                         mask = 0xf; /* 0x7 */
943                         break;
944                 case 32:
945                         mask = 0x3; /* 0x1 */
946                         break;
947                 default:
948                         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unkown color format.\n");
949                         break;
950         }
951
952         return mask;
953 }
954
955 /* This is taken from the haiku driver */
956 static CARD8 NVGetAccelerationMask(ScrnInfoPtr pScrn, CARD8 bpp)
957 {
958         NVPtr pNv = NVPTR(pScrn);
959         CARD8 mask = 0;
960         /* Identical for NV04 */
961         if (pNv->Architecture == NV_ARCH_04) {
962                 return NVGetCRTCMask(pScrn, bpp);
963         } else {
964                 switch(bpp) {
965                         case 8:
966                                 mask = 0x3f;
967                                 break;
968                         case 15:
969                                 mask = 0x1f;
970                                 break;
971                         case 16:
972                                 mask = 0x1f;
973                                 break;
974                         case 24:
975                                 mask = 0x3f;
976                                 break;
977                         case 32:
978                                 mask = 0x0f;
979                                 break;
980                         default:
981                                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unkown color format.\n");
982                                 break;
983                 }
984         }
985
986         return mask;
987 }
988
989 static CARD32 NVGetVideoPitch(ScrnInfoPtr pScrn, CARD8 bpp)
990 {
991         NVPtr pNv = NVPTR(pScrn);
992         CARD8 crtc_mask, accel_mask = 0;
993         crtc_mask = NVGetCRTCMask(pScrn, bpp);
994         if (!pNv->NoAccel) {
995                 accel_mask = NVGetAccelerationMask(pScrn, bpp);
996         }
997
998         /* adhere to the largest granularity imposed */
999         if (accel_mask > crtc_mask) {
1000                 return (pScrn->virtualX + accel_mask) & ~accel_mask;
1001         } else {
1002                 return (pScrn->virtualX + crtc_mask) & ~crtc_mask;
1003         }
1004 }
1005
1006 #define NVPreInitFail(fmt, args...) do {                                    \
1007         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%d: "fmt, __LINE__, ##args); \
1008         if (pNv->pInt10)                                                    \
1009                 xf86FreeInt10(pNv->pInt10);                                 \
1010         NVFreeRec(pScrn);                                                   \
1011         return FALSE;                                                       \
1012 } while(0)
1013
1014 /* Mandatory */
1015 Bool
1016 NVPreInit(ScrnInfoPtr pScrn, int flags)
1017 {
1018         xf86CrtcConfigPtr xf86_config;
1019         NVPtr pNv;
1020         MessageType from;
1021         int i, max_width, max_height;
1022         ClockRangePtr clockRanges;
1023         const char *s;
1024         int config_mon_rates = FALSE;
1025         int num_crtc;
1026
1027         if (flags & PROBE_DETECT) {
1028                 EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
1029
1030                 if (!pEnt)
1031                         return FALSE;
1032
1033                 i = pEnt->index;
1034                 xfree(pEnt);
1035
1036                 if (xf86LoadSubModule(pScrn, "vbe")) {
1037                         vbeInfoPtr pVbe = VBEInit(NULL, i);
1038                         ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
1039                         vbeFree(pVbe);
1040                 }
1041
1042                 return TRUE;
1043         }
1044
1045         /*
1046          * Note: This function is only called once at server startup, and
1047          * not at the start of each server generation.  This means that
1048          * only things that are persistent across server generations can
1049          * be initialised here.  xf86Screens[] is (pScrn is a pointer to one
1050          * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()  
1051          * are too, and should be used for data that must persist across
1052          * server generations.
1053          *
1054          * Per-generation data should be allocated with
1055          * AllocateScreenPrivateIndex() from the ScreenInit() function.
1056          */
1057
1058         /* Check the number of entities, and fail if it isn't one. */
1059         if (pScrn->numEntities != 1)
1060                 return FALSE;
1061
1062         /* Allocate the NVRec driverPrivate */
1063         if (!NVGetRec(pScrn)) {
1064                 return FALSE;
1065         }
1066         pNv = NVPTR(pScrn);
1067
1068         /* Get the entity, and make sure it is PCI. */
1069         pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
1070         if (pNv->pEnt->location.type != BUS_PCI)
1071                 return FALSE;
1072  
1073         /* Find the PCI info for this screen */
1074         pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index);
1075 #ifndef XSERVER_LIBPCIACCESS
1076         pNv->PciTag = pciTag(pNv->PciInfo->bus, pNv->PciInfo->device,
1077                                 pNv->PciInfo->func);
1078 #endif /* XSERVER_LIBPCIACCESS */
1079
1080         pNv->Primary = xf86IsPrimaryPci(pNv->PciInfo);
1081
1082         /* Initialize the card through int10 interface if needed */
1083         if (xf86LoadSubModule(pScrn, "int10")) {
1084                 xf86LoaderReqSymLists(int10Symbols, NULL);
1085 #if !defined(__alpha__) && !defined(__powerpc__)
1086                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");
1087                 pNv->pInt10 = xf86InitInt10(pNv->pEnt->index);
1088 #endif
1089         }
1090
1091         xf86SetOperatingState(resVgaIo, pNv->pEnt->index, ResUnusedOpr);
1092         xf86SetOperatingState(resVgaMem, pNv->pEnt->index, ResDisableOpr);
1093
1094         /* Set pScrn->monitor */
1095         pScrn->monitor = pScrn->confScreen->monitor;
1096
1097         volatile uint32_t *regs = NULL;
1098 #ifdef XSERVER_LIBPCIACCESS
1099         pci_device_map_range(pNv->PciInfo, PCI_DEV_MEM_BASE(pNv->PciInfo, 0),
1100                              0x90000, 0, (void *)&regs);
1101         pNv->Chipset = NVGetPCIID(regs) & 0xffff;
1102         pNv->NVArch = NVGetArchitecture(regs);
1103         pci_device_unmap_range(pNv->PciInfo, (void *) regs, 0x90000);
1104 #else
1105         CARD32 pcicmd;
1106         PCI_DEV_READ_LONG(pNv->PciInfo, PCI_CMD_STAT_REG, &pcicmd);
1107         /* Enable reading memory? */
1108         PCI_DEV_WRITE_LONG(pNv->PciInfo, PCI_CMD_STAT_REG, pcicmd | PCI_CMD_MEM_ENABLE);
1109         regs = xf86MapPciMem(-1, VIDMEM_MMIO, pNv->PciTag, PCI_DEV_MEM_BASE(pNv->PciInfo, 0), 0x90000);
1110         pNv->Chipset = NVGetPCIID(regs) & 0xffff;
1111         pNv->NVArch = NVGetArchitecture(regs);
1112         xf86UnMapVidMem(-1, (pointer)regs, 0x90000);
1113         /* Reset previous state */
1114         PCI_DEV_WRITE_LONG(pNv->PciInfo, PCI_CMD_STAT_REG, pcicmd);
1115 #endif /* XSERVER_LIBPCIACCESS */
1116
1117         pScrn->chipset = malloc(sizeof(char) * 25);
1118         sprintf(pScrn->chipset, "NVIDIA NV%02X", pNv->NVArch);
1119
1120         if(!pScrn->chipset) {
1121                 pScrn->chipset = "Unknown NVIDIA";
1122         }
1123
1124         /*
1125         * This shouldn't happen because such problems should be caught in
1126         * NVProbe(), but check it just in case.
1127         */
1128         if (pScrn->chipset == NULL)
1129                 NVPreInitFail("ChipID 0x%04X is not recognised\n", pNv->Chipset);
1130
1131         if (pNv->NVArch < 0x04)
1132                 NVPreInitFail("Chipset \"%s\" is not recognised\n", pScrn->chipset);
1133
1134         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Chipset: \"%s\"\n", pScrn->chipset);
1135
1136         /* The highest architecture currently supported is NV5x */
1137         if (pNv->NVArch >= 0x80) {
1138                 pNv->Architecture =  NV_ARCH_50;
1139         } else if (pNv->NVArch >= 0x60) {
1140                 pNv->Architecture =  NV_ARCH_40;
1141         } else if (pNv->NVArch >= 0x50) {
1142                 pNv->Architecture =  NV_ARCH_50;
1143         } else if (pNv->NVArch >= 0x40) {
1144                 pNv->Architecture =  NV_ARCH_40;
1145         } else if (pNv->NVArch >= 0x30) {
1146                 pNv->Architecture = NV_ARCH_30;
1147         } else if (pNv->NVArch >= 0x20) {
1148                 pNv->Architecture = NV_ARCH_20;
1149         } else if (pNv->NVArch >= 0x10) {
1150                 pNv->Architecture = NV_ARCH_10;
1151         } else if (pNv->NVArch >= 0x04) {
1152                 pNv->Architecture = NV_ARCH_04;
1153         /*  The lowest architecture currently supported is NV04 */
1154         } else {
1155                 return FALSE;
1156         }
1157
1158         /*
1159          * The first thing we should figure out is the depth, bpp, etc.
1160          */
1161
1162         if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
1163                 NVPreInitFail("\n");
1164         } else {
1165                 /* Check that the returned depth is one we support */
1166                 switch (pScrn->depth) {
1167                         case 8:
1168                         case 15:
1169                         case 16:
1170                         case 24:
1171                                 /* OK */
1172                                 break;
1173                         default:
1174                                 NVPreInitFail("Given depth (%d) is not supported by this driver\n",
1175                                         pScrn->depth);
1176                 }
1177         }
1178         xf86PrintDepthBpp(pScrn);
1179
1180         /*
1181          * This must happen after pScrn->display has been set because
1182          * xf86SetWeight references it.
1183          */
1184         if (pScrn->depth > 8) {
1185                 /* The defaults are OK for us */
1186                 rgb zeros = {0, 0, 0};
1187
1188                 if (!xf86SetWeight(pScrn, zeros, zeros)) {
1189                         NVPreInitFail("\n");
1190                 }
1191         }
1192
1193         if (!xf86SetDefaultVisual(pScrn, -1)) {
1194                 NVPreInitFail("\n");
1195         } else {
1196                 /* We don't currently support DirectColor at > 8bpp */
1197                 if (pScrn->depth > 8 && (pScrn->defaultVisual != TrueColor)) {
1198                         NVPreInitFail("Given default visual"
1199                                 " (%s) is not supported at depth %d\n",
1200                                 xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
1201                 }
1202         }
1203
1204         /* The vgahw module should be loaded here when needed */
1205         if (!xf86LoadSubModule(pScrn, "vgahw")) {
1206                 NVPreInitFail("\n");
1207         }
1208
1209         xf86LoaderReqSymLists(vgahwSymbols, NULL);
1210
1211         /*
1212          * Allocate a vgaHWRec
1213          */
1214         if (!vgaHWGetHWRec(pScrn)) {
1215                 NVPreInitFail("\n");
1216         }
1217
1218         /* We use a programmable clock */
1219         pScrn->progClock = TRUE;
1220
1221         /* Collect all of the relevant option flags (fill in pScrn->options) */
1222         xf86CollectOptions(pScrn, NULL);
1223
1224         /* Process the options */
1225         if (!(pNv->Options = xalloc(sizeof(NVOptions))))
1226                 return FALSE;
1227         memcpy(pNv->Options, NVOptions, sizeof(NVOptions));
1228         xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options);
1229
1230         /* Set the bits per RGB for 8bpp mode */
1231         if (pScrn->depth == 8)
1232                 pScrn->rgbBits = 8;
1233
1234         from = X_DEFAULT;
1235
1236         if (pNv->Architecture == NV_ARCH_50) {
1237                 pNv->randr12_enable = TRUE;
1238         } else {
1239                 pNv->randr12_enable = FALSE;
1240                 if (xf86ReturnOptValBool(pNv->Options, OPTION_RANDR12, FALSE)) {
1241                         pNv->randr12_enable = TRUE;
1242                 }
1243         }
1244         xf86DrvMsg(pScrn->scrnIndex, from, "Randr1.2 support %sabled\n", pNv->randr12_enable ? "en" : "dis");
1245
1246         pNv->new_restore = FALSE;
1247
1248         if (pNv->randr12_enable) {
1249                 if (xf86ReturnOptValBool(pNv->Options, OPTION_NEW_RESTORE, FALSE)) {
1250                         pNv->new_restore = TRUE;
1251                 }
1252                 xf86DrvMsg(pScrn->scrnIndex, from, "New (experimental) restore support %sabled\n", pNv->new_restore ? "en" : "dis");
1253         }
1254
1255         pNv->HWCursor = TRUE;
1256         /*
1257          * The preferred method is to use the "hw cursor" option as a tri-state
1258          * option, with the default set above.
1259          */
1260         if (xf86GetOptValBool(pNv->Options, OPTION_HW_CURSOR, &pNv->HWCursor)) {
1261                 from = X_CONFIG;
1262         }
1263         /* For compatibility, accept this too (as an override) */
1264         if (xf86ReturnOptValBool(pNv->Options, OPTION_SW_CURSOR, FALSE)) {
1265                 from = X_CONFIG;
1266                 pNv->HWCursor = FALSE;
1267         }
1268         xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
1269                 pNv->HWCursor ? "HW" : "SW");
1270
1271         pNv->FpScale = TRUE;
1272
1273         if (xf86GetOptValBool(pNv->Options, OPTION_FP_SCALE, &pNv->FpScale)) {
1274                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Flat panel scaling %s\n",
1275                         pNv->FpScale ? "on" : "off");
1276         }
1277         if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) {
1278                 pNv->NoAccel = TRUE;
1279                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
1280         }
1281         if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) {
1282                 pNv->ShadowFB = TRUE;
1283                 pNv->NoAccel = TRUE;
1284                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1285                         "Using \"Shadow Framebuffer\" - acceleration disabled\n");
1286         }
1287
1288         pNv->Rotate = 0;
1289         pNv->RandRRotation = FALSE;
1290         /*
1291          * Rotation with a randr-1.2 driver happens at a different level, so ignore these options.
1292          */
1293         if ((s = xf86GetOptValString(pNv->Options, OPTION_ROTATE)) && !pNv->randr12_enable) {
1294                 if(!xf86NameCmp(s, "CW")) {
1295                         pNv->ShadowFB = TRUE;
1296                         pNv->NoAccel = TRUE;
1297                         pNv->HWCursor = FALSE;
1298                         pNv->Rotate = 1;
1299                         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1300                                 "Rotating screen clockwise - acceleration disabled\n");
1301                 } else if(!xf86NameCmp(s, "CCW")) {
1302                         pNv->ShadowFB = TRUE;
1303                         pNv->NoAccel = TRUE;
1304                         pNv->HWCursor = FALSE;
1305                         pNv->Rotate = -1;
1306                         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1307                                 "Rotating screen counter clockwise - acceleration disabled\n");
1308                 } else if(!xf86NameCmp(s, "RandR")) {
1309                         pNv->ShadowFB = TRUE;
1310                         pNv->NoAccel = TRUE;
1311                         pNv->HWCursor = FALSE;
1312                         pNv->RandRRotation = TRUE;
1313                         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1314                                 "Using RandR rotation - acceleration disabled\n");
1315                 } else {
1316                         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
1317                                 "\"%s\" is not a valid value for Option \"Rotate\"\n", s);
1318                         xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
1319                                 "Valid options are \"CW\", \"CCW\", and \"RandR\"\n");
1320                 }
1321         }
1322
1323         if(xf86GetOptValInteger(pNv->Options, OPTION_VIDEO_KEY, &(pNv->videoKey))) {
1324                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
1325                                         pNv->videoKey);
1326         } else {
1327                 pNv->videoKey =  (1 << pScrn->offset.red) | 
1328                                         (1 << pScrn->offset.green) |
1329                 (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue);
1330         }
1331
1332         /* Things happen on a per output basis for a randr-1.2 driver. */
1333         if (xf86GetOptValBool(pNv->Options, OPTION_FLAT_PANEL, &(pNv->FlatPanel)) && !pNv->randr12_enable) {
1334                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "forcing %s usage\n",
1335                         pNv->FlatPanel ? "DFP" : "CRTC");
1336         } else {
1337                 pNv->FlatPanel = -1; /* autodetect later */
1338         }
1339
1340         pNv->FPDither = FALSE;
1341         if (xf86GetOptValBool(pNv->Options, OPTION_FP_DITHER, &(pNv->FPDither))) 
1342                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "enabling flat panel dither\n");
1343
1344         if (xf86GetOptValInteger(pNv->Options, OPTION_FP_TWEAK, 
1345                                                 &pNv->PanelTweak)) {
1346                 pNv->usePanelTweak = TRUE;
1347         } else {
1348                 pNv->usePanelTweak = FALSE;
1349         }
1350
1351         if (pNv->pEnt->device->MemBase != 0) {
1352                 /* Require that the config file value matches one of the PCI values. */
1353                 if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->MemBase)) {
1354                         NVPreInitFail(
1355                                 "MemBase 0x%08lX doesn't match any PCI base register.\n",
1356                                 pNv->pEnt->device->MemBase);
1357                 }
1358                 pNv->VRAMPhysical = pNv->pEnt->device->MemBase;
1359                 from = X_CONFIG;
1360         } else {
1361                 if (PCI_DEV_MEM_BASE(pNv->PciInfo, 1) != 0) {
1362                         pNv->VRAMPhysical = PCI_DEV_MEM_BASE(pNv->PciInfo, 1) & 0xff800000;
1363                         from = X_PROBED;
1364                 } else {
1365                         NVPreInitFail("No valid FB address in PCI config space\n");
1366                         return FALSE;
1367                 }
1368         }
1369         xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
1370                 (unsigned long)pNv->VRAMPhysical);
1371
1372         if (pNv->pEnt->device->IOBase != 0) {
1373                 /* Require that the config file value matches one of the PCI values. */
1374                 if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->IOBase)) {
1375                         NVPreInitFail("IOBase 0x%08lX doesn't match any PCI base register.\n",
1376                                 pNv->pEnt->device->IOBase);
1377                 }
1378                 pNv->IOAddress = pNv->pEnt->device->IOBase;
1379                 from = X_CONFIG;
1380         } else {
1381                 if (PCI_DEV_MEM_BASE(pNv->PciInfo, 0) != 0) {
1382                         pNv->IOAddress = PCI_DEV_MEM_BASE(pNv->PciInfo, 0) & 0xffffc000;
1383                         from = X_PROBED;
1384                 } else {
1385                         NVPreInitFail("No valid MMIO address in PCI config space\n");
1386                 }
1387         }
1388         xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
1389                 (unsigned long)pNv->IOAddress);
1390
1391         if (xf86RegisterResources(pNv->pEnt->index, NULL, ResExclusive))
1392                 NVPreInitFail("xf86RegisterResources() found resource conflicts\n");
1393
1394         if(pNv->Architecture < NV_ARCH_10) {
1395                 max_width = (pScrn->bitsPerPixel > 16) ? 2032 : 2048;
1396                 max_height = 2048;
1397         } else {
1398                 max_width = (pScrn->bitsPerPixel > 16) ? 4080 : 4096;
1399                 max_height = 4096;
1400         }
1401
1402         if (pNv->randr12_enable) {
1403                 /* Allocate an xf86CrtcConfig */
1404                 xf86CrtcConfigInit(pScrn, &nv_xf86crtc_config_funcs);
1405                 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1406
1407                 xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height);
1408         }
1409
1410         if (NVPreInitDRI(pScrn) == FALSE) {
1411                 NVPreInitFail("\n");
1412         }
1413
1414         if (!pNv->randr12_enable) {
1415                 if ((pScrn->monitor->nHsync == 0) && 
1416                         (pScrn->monitor->nVrefresh == 0)) {
1417
1418                         config_mon_rates = FALSE;
1419                 } else {
1420                         config_mon_rates = TRUE;
1421                 }
1422         }
1423
1424         NVCommonSetup(pScrn);
1425
1426         if (pNv->randr12_enable) {
1427                 if (pNv->Architecture == NV_ARCH_50)
1428                         if (!NV50DispPreInit(pScrn))
1429                                 NVPreInitFail("\n");
1430
1431                 NVI2CInit(pScrn);
1432
1433                 num_crtc = pNv->twoHeads ? 2 : 1;
1434                 for (i = 0; i < num_crtc; i++) {
1435                         nv_crtc_init(pScrn, i);
1436                 }
1437
1438                 NvSetupOutputs(pScrn);
1439
1440                 if (!xf86InitialConfiguration(pScrn, FALSE))
1441                         NVPreInitFail("No valid modes.\n");
1442         }
1443
1444         pScrn->videoRam = pNv->RamAmountKBytes;
1445         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kBytes\n",
1446                 pScrn->videoRam);
1447
1448         pNv->VRAMPhysicalSize = pScrn->videoRam * 1024;
1449
1450         /*
1451          * If the driver can do gamma correction, it should call xf86SetGamma()
1452          * here.
1453          */
1454
1455         {
1456                 Gamma zeros = {0.0, 0.0, 0.0};
1457
1458                 if (!xf86SetGamma(pScrn, zeros)) {
1459                         NVPreInitFail("\n");
1460                 }
1461         }
1462
1463         /*
1464          * Setup the ClockRanges, which describe what clock ranges are available,
1465          * and what sort of modes they can be used for.
1466          */
1467
1468         clockRanges = xnfcalloc(sizeof(ClockRange), 1);
1469         clockRanges->next = NULL;
1470         clockRanges->minClock = pNv->MinVClockFreqKHz;
1471         clockRanges->maxClock = pNv->MaxVClockFreqKHz;
1472         clockRanges->clockIndex = -1;           /* programmable */
1473         clockRanges->doubleScanAllowed = TRUE;
1474         if ((pNv->Architecture == NV_ARCH_20) ||
1475                 ((pNv->Architecture == NV_ARCH_10) && 
1476                 ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10) &&
1477                 ((pNv->Chipset & 0x0ff0) != CHIPSET_NV15))) {
1478                 /* HW is broken */
1479                 clockRanges->interlaceAllowed = FALSE;
1480         } else {
1481                 clockRanges->interlaceAllowed = TRUE;
1482         }
1483
1484         if(pNv->FlatPanel == 1) {
1485                 clockRanges->interlaceAllowed = FALSE;
1486                 clockRanges->doubleScanAllowed = FALSE;
1487         }
1488
1489 #ifdef M_T_DRIVER
1490         /* If DFP, add a modeline corresponding to its panel size */
1491         if (pNv->FlatPanel && !pNv->Television && pNv->fpWidth && pNv->fpHeight) {
1492                 DisplayModePtr Mode;
1493
1494                 Mode = xnfcalloc(1, sizeof(DisplayModeRec));
1495                 Mode = xf86CVTMode(pNv->fpWidth, pNv->fpHeight, 60.00, TRUE, FALSE);
1496                 Mode->type = M_T_DRIVER;
1497                 pScrn->monitor->Modes = xf86ModesAdd(pScrn->monitor->Modes, Mode);
1498
1499                 if (!config_mon_rates) {
1500                         if (!Mode->HSync)
1501                                 Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal);
1502                         if (!Mode->VRefresh)
1503                                 Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) /
1504                                                         ((float) (Mode->HTotal * Mode->VTotal));
1505
1506                         if (Mode->HSync < pScrn->monitor->hsync[0].lo)
1507                                 pScrn->monitor->hsync[0].lo = Mode->HSync;
1508                         if (Mode->HSync > pScrn->monitor->hsync[0].hi)
1509                                 pScrn->monitor->hsync[0].hi = Mode->HSync;
1510                         if (Mode->VRefresh < pScrn->monitor->vrefresh[0].lo)
1511                                 pScrn->monitor->vrefresh[0].lo = Mode->VRefresh;
1512                         if (Mode->VRefresh > pScrn->monitor->vrefresh[0].hi)
1513                                 pScrn->monitor->vrefresh[0].hi = Mode->VRefresh;
1514
1515                         pScrn->monitor->nHsync = 1;
1516                         pScrn->monitor->nVrefresh = 1;
1517                 }
1518         }
1519 #endif
1520
1521         if (pNv->randr12_enable) {
1522                 pScrn->displayWidth = NVGetVideoPitch(pScrn, pScrn->depth);
1523         } else {
1524                 /*
1525                  * xf86ValidateModes will check that the mode HTotal and VTotal values
1526                  * don't exceed the chipset's limit if pScrn->maxHValue and
1527                  * pScrn->maxVValue are set.  Since our NVValidMode() already takes
1528                  * care of this, we don't worry about setting them here.
1529                  */
1530                 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
1531                                         pScrn->display->modes, clockRanges,
1532                                         NULL, 256, max_width,
1533                                         512, 128, max_height,
1534                                         pScrn->display->virtualX,
1535                                         pScrn->display->virtualY,
1536                                         pNv->VRAMPhysicalSize / 2,
1537                                         LOOKUP_BEST_REFRESH);
1538
1539                 if (i == -1) {
1540                         NVPreInitFail("\n");
1541                 }
1542
1543                 /* Prune the modes marked as invalid */
1544                 xf86PruneDriverModes(pScrn);
1545
1546                 /*
1547                  * Set the CRTC parameters for all of the modes based on the type
1548                  * of mode, and the chipset's interlace requirements.
1549                  *
1550                  * Calling this is required if the mode->Crtc* values are used by the
1551                  * driver and if the driver doesn't provide code to set them.  They
1552                  * are not pre-initialised at all.
1553                  */
1554                 xf86SetCrtcForModes(pScrn, 0);
1555         }
1556
1557         if (pScrn->modes == NULL) {
1558                 NVPreInitFail("No valid modes found\n");
1559         }
1560
1561         /* Set the current mode to the first in the list */
1562         pScrn->currentMode = pScrn->modes;
1563
1564         /* Print the list of modes being used */
1565         xf86PrintModes(pScrn);
1566
1567         /* Set display resolution */
1568         xf86SetDpi(pScrn, 0, 0);
1569
1570
1571         /*
1572          * XXX This should be taken into account in some way in the mode valdation
1573          * section.
1574          */
1575
1576         if (xf86LoadSubModule(pScrn, "fb") == NULL) {
1577                 NVPreInitFail("\n");
1578         }
1579
1580         xf86LoaderReqSymLists(fbSymbols, NULL);
1581
1582         /* Load EXA if needed */
1583         if (!pNv->NoAccel) {
1584                 if (!xf86LoadSubModule(pScrn, "exa")) {
1585                         NVPreInitFail("\n");
1586                 }
1587                 xf86LoaderReqSymLists(exaSymbols, NULL);
1588         }
1589
1590         /* Load ramdac if needed */
1591         if (pNv->HWCursor) {
1592                 if (!xf86LoadSubModule(pScrn, "ramdac")) {
1593                         NVPreInitFail("\n");
1594                 }
1595                 xf86LoaderReqSymLists(ramdacSymbols, NULL);
1596         }
1597
1598         /* Load shadowfb if needed */
1599         if (pNv->ShadowFB) {
1600                 if (!xf86LoadSubModule(pScrn, "shadowfb")) {
1601                         NVPreInitFail("\n");
1602                 }
1603                 xf86LoaderReqSymLists(shadowSymbols, NULL);
1604         }
1605
1606         xf86FreeInt10(pNv->pInt10);
1607
1608         pNv->pInt10 = NULL;
1609         return TRUE;
1610 }
1611
1612
1613 /*
1614  * Map the framebuffer and MMIO memory.
1615  */
1616
1617 static Bool
1618 NVMapMem(ScrnInfoPtr pScrn)
1619 {
1620         NVPtr pNv = NVPTR(pScrn);
1621         int gart_scratch_size;
1622         uint64_t res;
1623
1624         nouveau_device_get_param(pNv->dev, NOUVEAU_GETPARAM_FB_SIZE, &res);
1625         pNv->VRAMSize=res;
1626         nouveau_device_get_param(pNv->dev, NOUVEAU_GETPARAM_FB_PHYSICAL, &res);
1627         pNv->VRAMPhysical=res;
1628         nouveau_device_get_param(pNv->dev, NOUVEAU_GETPARAM_AGP_SIZE, &res);
1629         pNv->AGPSize=res;
1630
1631 #if !NOUVEAU_EXA_PIXMAPS
1632         if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
1633                 0, pNv->VRAMPhysicalSize / 2, &pNv->FB)) {
1634                         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate memory for framebuffer!\n");
1635                         return FALSE;
1636         }
1637         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1638                 "Allocated %dMiB VRAM for framebuffer + offscreen pixmaps\n",
1639                 (unsigned int)(pNv->FB->size >> 20));
1640 #endif
1641
1642         if (pNv->AGPSize) {
1643                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1644                            "AGPGART: %dMiB available\n",
1645                            (unsigned int)(pNv->AGPSize >> 20));
1646                 if (pNv->AGPSize > (16*1024*1024))
1647                         gart_scratch_size = 16*1024*1024;
1648                 else
1649                         /* always leave 512kb for other things like the fifos */
1650                         gart_scratch_size = pNv->AGPSize - 512*1024;
1651         } else {
1652                 gart_scratch_size = (4 << 20) - (1 << 18) ;
1653                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1654                            "GART: PCI DMA - using %dKiB\n",
1655                            gart_scratch_size >> 10);
1656         }
1657
1658         if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_GART | NOUVEAU_BO_PIN, 0,
1659                            gart_scratch_size, &pNv->GART)) {
1660                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1661                            "Unable to allocate GART memory\n");
1662         }
1663         if (pNv->GART) {
1664                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1665                            "GART: Allocated %dMiB as a scratch buffer\n",
1666                            (unsigned int)(pNv->GART->size >> 20));
1667         }
1668
1669         if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN, 0,
1670                            64 * 1024, &pNv->Cursor)) {
1671                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1672                            "Failed to allocate memory for hardware cursor\n");
1673                 return FALSE;
1674         }
1675
1676         if (pNv->randr12_enable) {
1677                 if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN, 0,
1678                         64 * 1024, &pNv->Cursor2)) {
1679                         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1680                                 "Failed to allocate memory for hardware cursor\n");
1681                         return FALSE;
1682                 }
1683         }
1684
1685         if (pNv->Architecture >= NV_ARCH_50) {
1686                 /* Both CRTC's have a CLUT. */
1687                 if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
1688                                    0, 0x1000, &pNv->CLUT0)) {
1689                         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1690                                    "Failed to allocate memory for CLUT0\n");
1691                         return FALSE;
1692                 }
1693
1694                 if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
1695                                    0, 0x1000, &pNv->CLUT1)) {
1696                         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1697                                    "Failed to allocate memory for CLUT1\n");
1698                         return FALSE;
1699                 }
1700         }
1701
1702         if ((pNv->FB && nouveau_bo_map(pNv->FB, NOUVEAU_BO_RDWR)) ||
1703             (pNv->GART && nouveau_bo_map(pNv->GART, NOUVEAU_BO_RDWR)) ||
1704             (pNv->CLUT0 && nouveau_bo_map(pNv->CLUT0, NOUVEAU_BO_RDWR)) ||
1705             (pNv->CLUT1 && nouveau_bo_map(pNv->CLUT1, NOUVEAU_BO_RDWR)) ||
1706             nouveau_bo_map(pNv->Cursor, NOUVEAU_BO_RDWR) ||
1707             (pNv->randr12_enable && nouveau_bo_map(pNv->Cursor2, NOUVEAU_BO_RDWR))) {
1708                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1709                            "Failed to map pinned buffers\n");
1710                 return FALSE;
1711         }
1712
1713         return TRUE;
1714 }
1715
1716 /*
1717  * Unmap the framebuffer and MMIO memory.
1718  */
1719
1720 static Bool
1721 NVUnmapMem(ScrnInfoPtr pScrn)
1722 {
1723         NVPtr pNv = NVPTR(pScrn);
1724
1725         nouveau_bo_del(&pNv->FB);
1726         nouveau_bo_del(&pNv->GART);
1727         nouveau_bo_del(&pNv->Cursor);
1728         if (pNv->randr12_enable) {
1729                 nouveau_bo_del(&pNv->Cursor2);
1730         }
1731         nouveau_bo_del(&pNv->CLUT0);
1732         nouveau_bo_del(&pNv->CLUT1);
1733
1734         return TRUE;
1735 }
1736
1737
1738 /*
1739  * Initialise a new mode. 
1740  */
1741
1742 static Bool
1743 NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1744 {
1745     vgaHWPtr hwp = VGAHWPTR(pScrn);
1746     vgaRegPtr vgaReg;
1747     NVPtr pNv = NVPTR(pScrn);
1748     NVRegPtr nvReg;
1749
1750     /* Initialise the ModeReg values */
1751     if (!vgaHWInit(pScrn, mode))
1752         return FALSE;
1753     pScrn->vtSema = TRUE;
1754
1755     vgaReg = &hwp->ModeReg;
1756     nvReg = &pNv->ModeReg;
1757
1758     if(!NVDACInit(pScrn, mode))
1759         return FALSE;
1760
1761     NVLockUnlock(pScrn, 0);
1762     if(pNv->twoHeads) {
1763         nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, nvReg->crtcOwner);
1764         NVLockUnlock(pScrn, 0);
1765     }
1766
1767     /* Program the registers */
1768     vgaHWProtect(pScrn, TRUE);
1769
1770     NVDACRestore(pScrn, vgaReg, nvReg, FALSE);
1771
1772 #if X_BYTE_ORDER == X_BIG_ENDIAN
1773     /* turn on LFB swapping */
1774     {
1775         unsigned char tmp;
1776
1777         tmp = nvReadCurVGA(pNv, NV_VGA_CRTCX_SWAPPING);
1778         tmp |= (1 << 7);
1779         nvWriteCurVGA(pNv, NV_VGA_CRTCX_SWAPPING, tmp);
1780     }
1781 #endif
1782
1783     if (!pNv->NoAccel)
1784                 NVAccelCommonInit(pScrn);
1785
1786     vgaHWProtect(pScrn, FALSE);
1787
1788     pScrn->currentMode = mode;
1789
1790     return TRUE;
1791 }
1792
1793 #define NV_MODE_PRIVATE_ID 0x4F37ED65
1794 #define NV_MODE_PRIVATE_SIZE 2
1795
1796 /* 
1797  * Match a private mode flag in a special function.
1798  * I don't want ugly casting all over the code.
1799  */
1800 Bool
1801 NVMatchModePrivate(DisplayModePtr mode, uint32_t flags)
1802 {
1803         if (!mode)
1804                 return FALSE;
1805         if (!mode->Private)
1806                 return FALSE;
1807         if (mode->PrivSize != NV_MODE_PRIVATE_SIZE)
1808                 return FALSE;
1809         if (mode->Private[0] != NV_MODE_PRIVATE_ID)
1810                 return FALSE;
1811
1812         if (mode->Private[1] & flags)
1813                 return TRUE;
1814
1815         return FALSE;
1816 }
1817
1818 static void
1819 NVRestoreConsole(xf86OutputPtr output, DisplayModePtr mode)
1820 {
1821         if (!output->crtc)
1822                 return;
1823
1824         xf86CrtcPtr crtc = output->crtc;
1825         Bool need_unlock;
1826
1827         if (!crtc->enabled)
1828                 return;
1829
1830         xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
1831         DisplayModePtr adjusted_mode = xf86DuplicateMode(mode);
1832
1833         /* Sequence mimics a normal modeset. */
1834         output->funcs->dpms(output, DPMSModeOff);
1835         crtc->funcs->dpms(crtc, DPMSModeOff);
1836         need_unlock = crtc->funcs->lock(crtc);
1837         output->funcs->mode_fixup(output, mode, adjusted_mode);
1838         crtc->funcs->mode_fixup(crtc, mode, adjusted_mode);
1839         output->funcs->prepare(output);
1840         crtc->funcs->prepare(crtc);
1841         /* Always use offset (0,0). */
1842         crtc->funcs->mode_set(crtc, mode, adjusted_mode, 0, 0);
1843         output->funcs->mode_set(output, mode, adjusted_mode);
1844         crtc->funcs->commit(crtc);
1845         output->funcs->commit(output);
1846         if (need_unlock)
1847                 crtc->funcs->unlock(crtc);
1848         /* Always turn on outputs afterwards. */
1849         output->funcs->dpms(output, DPMSModeOn);
1850         crtc->funcs->dpms(crtc, DPMSModeOn);
1851
1852         /* Free mode. */
1853         xfree(adjusted_mode);
1854 }
1855
1856 #define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DRIVER
1857 #define MODESUFFIX   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
1858
1859 /* hblankstart: 648, hblankend: 792, vblankstart: 407, vblankend: 442 for 640x400 */
1860 static DisplayModeRec VGAModes[2] = {
1861         { MODEPREFIX("640x400"),    28320, /*25175,*/ 640,  680,  776,  800, 0,  400,  412,  414,  449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 640x400 */
1862         { MODEPREFIX("720x400"),    28320,  720,  738,  846,  900, 0,  400,  412,  414,  449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@70Hz */
1863 };
1864
1865 /*
1866  * Restore the initial (text) mode.
1867  */
1868 static void 
1869 NVRestore(ScrnInfoPtr pScrn)
1870 {
1871         vgaHWPtr hwp = VGAHWPTR(pScrn);
1872         vgaRegPtr vgaReg = &hwp->SavedReg;
1873         NVPtr pNv = NVPTR(pScrn);
1874         NVRegPtr nvReg = &pNv->SavedReg;
1875
1876         if (pNv->randr12_enable) {
1877                 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1878                 RIVA_HW_STATE *state = &pNv->ModeReg;
1879                 int i;
1880
1881                 /* Let's wipe some state regs */
1882                 state->crtc_reg[0].vpll_a = 0;
1883                 state->crtc_reg[0].vpll_b = 0;
1884                 state->crtc_reg[1].vpll_a = 0;
1885                 state->crtc_reg[1].vpll_b = 0;
1886                 state->pllsel = 0;
1887                 state->crosswired = FALSE;
1888
1889                 if (pNv->new_restore) { /* new style restore. */
1890                         for (i = 0; i < xf86_config->num_crtc; i++) {
1891                                 NVCrtcLockUnlock(xf86_config->crtc[i], 0);
1892                         }
1893
1894                         /* Reset some values according to stored console value, to avoid confusion later on. */
1895                         /* Otherwise we end up with corrupted terminals. */
1896                         for (i = 0; i < xf86_config->num_crtc; i++) {
1897                                 NVCrtcPrivatePtr nv_crtc = xf86_config->crtc[i]->driver_private;
1898                                 RIVA_HW_STATE *state = &pNv->SavedReg;
1899                                 NVCrtcRegPtr savep = &state->crtc_reg[nv_crtc->head];
1900                                 uint8_t pixelDepth = pNv->console_mode[nv_crtc->head].depth/8;
1901                                 /* restore PIXEL value */
1902                                 uint32_t pixel = NVReadVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_PIXEL) & ~(0xF);
1903                                 pixel |= (pixelDepth > 2) ? 3 : pixelDepth;
1904                                 NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_PIXEL, pixel);
1905                                 /* restore HDisplay and VDisplay */
1906                                 NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_HDISPE, (pNv->console_mode[nv_crtc->head].x_res)/8 - 1);
1907                                 NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_VDISPE, (pNv->console_mode[nv_crtc->head].y_res) - 1);
1908                                 /* restore CR52 */
1909                                 NVWriteVgaCrtc(pNv, nv_crtc->head, NV_VGA_CRTCX_52, savep->CRTC[NV_VGA_CRTCX_52]);
1910                                 /* restore crtc base */
1911                                 NVCrtcWriteCRTC(xf86_config->crtc[i], NV_CRTC_START, pNv->console_mode[nv_crtc->head].fb_start);
1912                                 /* Restore general control */
1913                                 NVCrtcWriteRAMDAC(xf86_config->crtc[i], NV_RAMDAC_GENERAL_CONTROL, savep->general);
1914                                 /* Restore CR5758 */
1915                                 if (pNv->NVArch >= 0x17 && pNv->twoHeads)
1916                                         for (i = 0; i < 0x10; i++)
1917                                                 NVWriteVgaCrtc5758(pNv, nv_crtc->head, i, savep->CR58[i]);
1918                         }
1919
1920                         /* Restore outputs when enabled. */
1921                         for (i = 0; i < xf86_config->num_output; i++) {
1922                                 xf86OutputPtr output = xf86_config->output[i];
1923                                 if (!xf86_config->output[i]->crtc) /* not enabled? */
1924                                         continue;
1925
1926                                 NVOutputPrivatePtr nv_output = output->driver_private;
1927                                 Bool is_fp = FALSE;
1928                                 DisplayModePtr mode = NULL;
1929                                 DisplayModePtr good_mode = NULL;
1930                                 NVConsoleMode *console = &pNv->console_mode[i];
1931                                 DisplayModePtr modes = output->probed_modes;
1932                                 if (!modes) /* no modes means no restore */
1933                                         continue;
1934
1935                                 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS)
1936                                         is_fp = TRUE;
1937
1938                                 if (console->vga_mode) {
1939                                         /* We support 640x400 and 720x400 vga modes. */
1940                                         if (console->x_res == 720)
1941                                                 good_mode = &VGAModes[1];
1942                                         else
1943                                                 good_mode = &VGAModes[0];
1944                                         if (!good_mode) /* No suitable mode found. */
1945                                                 continue;
1946                                 } else {
1947                                         NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
1948                                         uint32_t old_clock = nv_get_clock_from_crtc(pScrn, &pNv->SavedReg, nv_crtc->head);
1949                                         uint32_t clock_diff = 0xFFFFFFFF;
1950                                         for (mode = modes; mode != NULL; mode = mode->next) {
1951                                                 /* We only have the first 8 bits of y_res - 1. */
1952                                                 /* And it's sometimes bogus. */
1953                                                 if (is_fp || !console->enabled) { /* digital outputs are run at their native clock */
1954                                                         if (mode->HDisplay == console->x_res) {
1955                                                                 if (!good_mode) /* Pick any match, in case we don't find a 60.0 Hz mode. */
1956                                                                         good_mode = mode;
1957                                                                 /* Pick a 60.0 Hz mode if there is one. */
1958                                                                 if (mode->VRefresh > 59.95 && mode->VRefresh < 60.05) {
1959                                                                         good_mode = mode;
1960                                                                         break;
1961                                                                 }
1962                                                         }
1963                                                 } else {
1964                                                         if (mode->HDisplay == console->x_res) {
1965                                                                 int temp_diff = mode->Clock - old_clock;
1966                                                                 if (temp_diff < 0)
1967                                                                         temp_diff *= -1;
1968                                                                 if (temp_diff < clock_diff) { /* converge on the closest mode */
1969                                                                         clock_diff = temp_diff;
1970                                                                         good_mode = mode;
1971                                                                 }
1972                                                         }
1973                                                 }
1974                                         }
1975                                         if (!good_mode) /* No suitable mode found. */
1976                                                 continue;
1977                                 }
1978
1979                                 mode = xf86DuplicateMode(good_mode);
1980
1981                                 INT32 *nv_mode = xnfcalloc(sizeof(INT32)*NV_MODE_PRIVATE_SIZE, 1);
1982
1983                                 /* A semi-unique identifier to avoid using other privates. */
1984                                 nv_mode[0] = NV_MODE_PRIVATE_ID;
1985
1986                                 if (console->vga_mode)
1987                                         nv_mode[1] |= NV_MODE_VGA;
1988
1989                                 nv_mode[1] |= NV_MODE_CONSOLE;
1990
1991                                 mode->Private = nv_mode;
1992                                 mode->PrivSize = NV_MODE_PRIVATE_SIZE;
1993
1994                                 uint8_t scale_backup = nv_output->scaling_mode;
1995                                 if (nv_output->type == OUTPUT_LVDS || nv_output->type == OUTPUT_TMDS)
1996                                         nv_output->scaling_mode = SCALE_FULLSCREEN;
1997
1998                                 NVRestoreConsole(output, mode);
1999
2000                                 /* Restore value, so we reenter X properly. */
2001                                 nv_output->scaling_mode = scale_backup;
2002
2003                                 xfree(mode->Private);
2004                                 xfree(mode);
2005                         }
2006
2007                         /* Force hide the cursor. */
2008                         for (i = 0; i < xf86_config->num_crtc; i++) {
2009                                 xf86_config->crtc[i]->funcs->hide_cursor(xf86_config->crtc[i]);
2010                         }
2011
2012                         /* Lock the crtc's. */
2013                         for (i = 0; i < xf86_config->num_crtc; i++) {
2014                                 NVCrtcLockUnlock(xf86_config->crtc[i], 1);
2015                         }
2016
2017                         /* Let's clean our slate once again, so we always rewrite vpll's upon returning to X. */
2018                         state->crtc_reg[0].vpll_a = 0;
2019                         state->crtc_reg[0].vpll_b = 0;
2020                         state->crtc_reg[1].vpll_a = 0;
2021                         state->crtc_reg[1].vpll_b = 0;
2022                         state->pllsel = 0;
2023                         state->crosswired = FALSE;
2024                 } else {
2025                         for (i = 0; i < xf86_config->num_crtc; i++)
2026                                 NVCrtcLockUnlock(xf86_config->crtc[i], 0);
2027
2028                         for (i = 0; i < xf86_config->num_output; i++)
2029                                 xf86_config->output[i]->funcs->restore(xf86_config->output[i]);
2030
2031                         for (i = 0; i < xf86_config->num_crtc; i++)
2032                                 xf86_config->crtc[i]->funcs->restore(xf86_config->crtc[i]);
2033
2034                         for (i = 0; i < xf86_config->num_crtc; i++)
2035                                 NVCrtcLockUnlock(xf86_config->crtc[i], 1);
2036                 }
2037         } else {
2038                 NVLockUnlock(pScrn, 0);
2039
2040                 if(pNv->twoHeads) {
2041                         nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->crtc_active[1] * 0x3);
2042                         NVLockUnlock(pScrn, 0);
2043                 }
2044
2045                 /* Only restore text mode fonts/text for the primary card */
2046                 vgaHWProtect(pScrn, TRUE);
2047                 NVDACRestore(pScrn, vgaReg, nvReg, pNv->Primary);
2048                 vgaHWProtect(pScrn, FALSE);
2049         }
2050
2051         if (pNv->twoHeads && !pNv->new_restore) {
2052                 NVSetOwner(pScrn, 0);   /* move to head A to set owner */
2053                 NVLockVgaCrtc(pNv, 0, false);
2054                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Restoring CRTC_OWNER to %d.\n", pNv->vtOWNER);
2055                 NVWriteVgaCrtc(pNv, 0, NV_VGA_CRTCX_OWNER, pNv->vtOWNER);
2056                 NVLockVgaCrtc(pNv, 0, true);
2057         }
2058 }
2059
2060 static void
2061 NVLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
2062               LOCO * colors, VisualPtr pVisual)
2063 {
2064         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2065         int c;
2066         int i, j, index;
2067         CARD16 lut_r[256], lut_g[256], lut_b[256];
2068
2069         for (c = 0; c < xf86_config->num_crtc; c++) {
2070                 xf86CrtcPtr crtc = xf86_config->crtc[c];
2071
2072                 if (crtc->enabled == 0)
2073                         continue;
2074
2075                 /* code borrowed from intel driver */
2076                 switch (pScrn->depth) {
2077                 case 15:
2078                         for (i = 0; i < numColors; i++) {
2079                                 index = indices[i];
2080                                 for (j = 0; j < 8; j++) {
2081                                         lut_r[index * 8 + j] = colors[index].red << 8;
2082                                         lut_g[index * 8 + j] = colors[index].green << 8;
2083                                         lut_b[index * 8 + j] = colors[index].blue << 8;
2084                                 }
2085                         }
2086                 case 16:
2087                         for (i = 0; i < numColors; i++) {
2088                                 index = indices[i];
2089
2090                                 if (i <= 31) {
2091                                         for (j = 0; j < 8; j++) {
2092                                                 lut_r[index * 8 + j] = colors[index].red << 8;
2093                                                 lut_b[index * 8 + j] = colors[index].blue << 8;
2094                                         }
2095                                 }
2096
2097                                 for (j = 0; j < 4; j++) {
2098                                         lut_g[index * 4 + j] = colors[index].green << 8;
2099                                 }
2100                         }
2101                 default:
2102                         for (i = 0; i < numColors; i++) {
2103                                 index = indices[i];
2104                                 lut_r[index] = colors[index].red << 8;
2105                                 lut_g[index] = colors[index].green << 8;
2106                                 lut_b[index] = colors[index].blue << 8;
2107                         }
2108                         break;
2109                 }
2110
2111                 /* Make the change through RandR */
2112                 RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
2113         }
2114 }
2115
2116 static void NVBacklightEnable(NVPtr pNv,  Bool on)
2117 {
2118     /* This is done differently on each laptop.  Here we
2119        define the ones we know for sure. */
2120
2121 #if defined(__powerpc__)
2122     if((pNv->Chipset == 0x10DE0179) || 
2123        (pNv->Chipset == 0x10DE0189) || 
2124        (pNv->Chipset == 0x10DE0329))
2125     {
2126        /* NV17,18,34 Apple iMac, iBook, PowerBook */
2127       CARD32 tmp_pmc, tmp_pcrt;
2128       tmp_pmc = nvReadMC(pNv, NV_PBUS_DEBUG_DUALHEAD_CTL) & 0x7FFFFFFF;
2129       tmp_pcrt = NVReadCRTC(pNv, 0, NV_CRTC_GPIO_EXT) & 0xFFFFFFFC;
2130       if(on) {
2131           tmp_pmc |= (1 << 31);
2132           tmp_pcrt |= 0x1;
2133       }
2134       nvWriteMC(pNv, NV_PBUS_DEBUG_DUALHEAD_CTL, tmp_pmc);
2135       NVWriteCRTC(pNv, 0, NV_CRTC_GPIO_EXT, tmp_pcrt);
2136     }
2137 #endif
2138     
2139     if(pNv->LVDS) {
2140        if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11)) {
2141            nvWriteMC(pNv, 0x130C, on ? 3 : 7);
2142        }
2143     } else {
2144        CARD32 fpcontrol;
2145
2146        fpcontrol = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL) & 0xCfffffCC;
2147
2148        /* cut the TMDS output */
2149        if(on) fpcontrol |= pNv->fpSyncs;
2150        else fpcontrol |= 0x20000022;
2151
2152        nvWriteCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL, fpcontrol);
2153     }
2154 }
2155
2156 static void
2157 NVDPMSSetLCD(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
2158 {
2159   NVPtr pNv = NVPTR(pScrn);
2160
2161   if (!pScrn->vtSema) return;
2162
2163   vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
2164
2165   switch (PowerManagementMode) {
2166   case DPMSModeStandby:  /* HSync: Off, VSync: On */
2167   case DPMSModeSuspend:  /* HSync: On, VSync: Off */
2168   case DPMSModeOff:      /* HSync: Off, VSync: Off */
2169     NVBacklightEnable(pNv, 0);
2170     break;
2171   case DPMSModeOn:       /* HSync: On, VSync: On */
2172     NVBacklightEnable(pNv, 1);
2173   default:
2174     break;
2175   }
2176 }
2177
2178
2179 static void
2180 NVDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
2181 {
2182   unsigned char crtc1A;
2183   vgaHWPtr hwp = VGAHWPTR(pScrn);
2184
2185   if (!pScrn->vtSema) return;
2186
2187   crtc1A = hwp->readCrtc(hwp, 0x1A) & ~0xC0;
2188
2189   switch (PowerManagementMode) {
2190   case DPMSModeStandby:  /* HSync: Off, VSync: On */
2191     crtc1A |= 0x80;
2192     break;
2193   case DPMSModeSuspend:  /* HSync: On, VSync: Off */
2194     crtc1A |= 0x40;
2195     break;
2196   case DPMSModeOff:      /* HSync: Off, VSync: Off */
2197     crtc1A |= 0xC0;
2198     break;
2199   case DPMSModeOn:       /* HSync: On, VSync: On */
2200   default:
2201     break;
2202   }
2203
2204   /* vgaHWDPMSSet will merely cut the dac output */
2205   vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
2206
2207   hwp->writeCrtc(hwp, 0x1A, crtc1A);
2208 }
2209
2210
2211 /* Mandatory */
2212
2213 /* This gets called at the start of each server generation */
2214
2215 static Bool
2216 NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
2217 {
2218         ScrnInfoPtr pScrn;
2219         vgaHWPtr hwp;
2220         NVPtr pNv;
2221         int ret;
2222         VisualPtr visual;
2223         unsigned char *FBStart;
2224         int width, height, displayWidth, shadowHeight, i;
2225
2226         /* 
2227          * First get the ScrnInfoRec
2228          */
2229         pScrn = xf86Screens[pScreen->myNum];
2230
2231         hwp = VGAHWPTR(pScrn);
2232         pNv = NVPTR(pScrn);
2233
2234         /* Map the VGA memory when the primary video */
2235         if (pNv->Primary) {
2236                 hwp->MapSize = 0x10000;
2237                 if (!vgaHWMapMem(pScrn))
2238                         return FALSE;
2239         }
2240
2241         /* First init DRI/DRM */
2242         if (!NVDRIScreenInit(pScrn))
2243                 return FALSE;
2244
2245         /* Allocate and map memory areas we need */
2246         if (!NVMapMem(pScrn))
2247                 return FALSE;
2248
2249         if (!pNv->NoAccel) {
2250                 /* Init DRM - Alloc FIFO */
2251                 if (!NVInitDma(pScrn))
2252                         return FALSE;
2253
2254                 /* setup graphics objects */
2255                 if (!NVAccelCommonInit(pScrn))
2256                         return FALSE;
2257         }
2258
2259 #if NOUVEAU_EXA_PIXMAPS
2260         if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
2261                         0, NOUVEAU_ALIGN(pScrn->virtualX, 64) * NOUVEAU_ALIGN(pScrn->virtualY, 64) *
2262                         (pScrn->bitsPerPixel >> 3), &pNv->FB)) {
2263                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate memory for screen pixmap.\n");
2264                 return FALSE;
2265         }
2266 #endif
2267
2268         if (!pNv->randr12_enable) {
2269                 /* Save the current state */
2270                 NVSave(pScrn);
2271                 /* Initialise the first mode */
2272                 if (!NVModeInit(pScrn, pScrn->currentMode))
2273                         return FALSE;
2274
2275                 /* Darken the screen for aesthetic reasons and set the viewport */
2276                 NVSaveScreen(pScreen, SCREEN_SAVER_ON);
2277                 pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
2278         } else {
2279                 pScrn->memPhysBase = pNv->VRAMPhysical;
2280                 pScrn->fbOffset = 0;
2281
2282                 /* Gather some misc info before the randr stuff kicks in */
2283                 for (i = 0; i <= pNv->twoHeads; i++) {
2284                         if (NVReadVgaCrtc(pNv, i, NV_VGA_CRTCX_PIXEL) & 0xf) { /* framebuffer mode */
2285                                 pNv->console_mode[i].vga_mode = FALSE;
2286                                 uint8_t var = NVReadVgaCrtc(pNv, i, NV_VGA_CRTCX_PIXEL) & 0xf;
2287                                 Bool filled = (NVReadRAMDAC(pNv, i, NV_RAMDAC_GENERAL_CONTROL) & 0x1000);
2288                                 switch (var){
2289                                         case 3:
2290                                                 if (filled)
2291                                                         pNv->console_mode[i].depth = 32;
2292                                                 else
2293                                                         pNv->console_mode[i].depth = 24;
2294                                                 /* This is pitch related. */
2295                                                 pNv->console_mode[i].bpp = 32;
2296                                                 break;
2297                                         case 2:
2298                                                 if (filled)
2299                                                         pNv->console_mode[i].depth = 16;
2300                                                 else
2301                                                         pNv->console_mode[i].depth = 15;
2302                                                 /* This is pitch related. */
2303                                                 pNv->console_mode[i].bpp = 16;
2304                                                 break;
2305                                         case 1:
2306                                                 /* 8bit mode is always filled? */
2307                                                 pNv->console_mode[i].depth = 8;
2308                                                 /* This is pitch related. */
2309                                                 pNv->console_mode[i].bpp = 8;
2310                                         default:
2311                                                 break;
2312                                 }
2313                         } else { /* vga mode */
2314                                 pNv->console_mode[i].vga_mode = TRUE;
2315                                 pNv->console_mode[i].bpp = 4;
2316                                 pNv->console_mode[i].depth = 4;
2317                         }
2318
2319                         pNv->console_mode[i].x_res = (NVReadVgaCrtc(pNv, i, NV_VGA_CRTCX_HDISPE) + 1) * 8;
2320                         pNv->console_mode[i].y_res = (NVReadVgaCrtc(pNv, i, NV_VGA_CRTCX_VDISPE) + 1); /* NV_VGA_CRTCX_VDISPE only contains the lower 8 bits. */
2321
2322                         pNv->console_mode[i].fb_start = NVReadCRTC(pNv, i, NV_CRTC_START);
2323
2324                         pNv->console_mode[i].enabled = FALSE;
2325
2326                         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRTC %d: Console mode: %dx%d depth: %d bpp: %d crtc_start: 0x%X.\n", i, pNv->console_mode[i].x_res, pNv->console_mode[i].y_res, pNv->console_mode[i].depth, pNv->console_mode[i].bpp, pNv->console_mode[i].fb_start);
2327                 }
2328
2329                 /* Check if crtc's were enabled. */
2330                 if (NVReadRAMDAC(pNv, 0, NV_RAMDAC_PLL_SELECT) & NV_RAMDAC_PLL_SELECT_PLL_SOURCE_VPLL) {
2331                         pNv->console_mode[0].enabled = TRUE;
2332                         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRTC 0 was enabled.\n");
2333                 }
2334
2335                 if (NVReadRAMDAC(pNv, 0, NV_RAMDAC_PLL_SELECT) & NV_RAMDAC_PLL_SELECT_PLL_SOURCE_VPLL2) {
2336                         pNv->console_mode[1].enabled = TRUE;
2337                         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRTC 1 was enabled.\n");
2338                 }
2339
2340                 if (!NVEnterVT(scrnIndex, 0))
2341                         return FALSE;
2342                 NVSaveScreen(pScreen, SCREEN_SAVER_ON);
2343         }
2344
2345
2346         /*
2347          * The next step is to setup the screen's visuals, and initialise the
2348          * framebuffer code.  In cases where the framebuffer's default
2349          * choices for things like visual layouts and bits per RGB are OK,
2350          * this may be as simple as calling the framebuffer's ScreenInit()
2351          * function.  If not, the visuals will need to be setup before calling
2352          * a fb ScreenInit() function and fixed up after.
2353          *
2354          * For most PC hardware at depths >= 8, the defaults that fb uses
2355          * are not appropriate.  In this driver, we fixup the visuals after.
2356          */
2357
2358         /*
2359          * Reset the visual list.
2360          */
2361         miClearVisualTypes();
2362
2363         /* Setup the visuals we support. */
2364
2365         if (!miSetVisualTypes(pScrn->depth, 
2366                                 miGetDefaultVisualMask(pScrn->depth), 8,
2367                                 pScrn->defaultVisual))
2368                 return FALSE;
2369         if (!miSetPixmapDepths ())
2370                 return FALSE;
2371
2372         /*
2373          * Call the framebuffer layer's ScreenInit function, and fill in other
2374          * pScreen fields.
2375          */
2376
2377         width = pScrn->virtualX;
2378         height = pScrn->virtualY;
2379         displayWidth = pScrn->displayWidth;
2380
2381         if(pNv->Rotate) {
2382                 height = pScrn->virtualX;
2383                 width = pScrn->virtualY;
2384         }
2385
2386         /* If RandR rotation is enabled, leave enough space in the
2387          * framebuffer for us to rotate the screen dimensions without
2388          * changing the pitch.
2389          */
2390         if(pNv->RandRRotation) {
2391                 shadowHeight = max(width, height);
2392         } else {
2393                 shadowHeight = height;
2394         }
2395
2396         if (pNv->ShadowFB) {
2397                 pNv->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
2398                 pNv->ShadowPtr = xalloc(pNv->ShadowPitch * shadowHeight);
2399                 displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3);
2400                 FBStart = pNv->ShadowPtr;
2401         } else {
2402                 pNv->ShadowPtr = NULL;
2403                 FBStart = pNv->FB->map;
2404         }
2405
2406         switch (pScrn->bitsPerPixel) {
2407                 case 8:
2408                 case 16:
2409                 case 32:
2410                         ret = fbScreenInit(pScreen, FBStart, width, height,
2411                                 pScrn->xDpi, pScrn->yDpi,
2412                                 displayWidth, pScrn->bitsPerPixel);
2413                         break;
2414                 default:
2415                         xf86DrvMsg(scrnIndex, X_ERROR,
2416                                 "Internal error: invalid bpp (%d) in NVScreenInit\n",
2417                                 pScrn->bitsPerPixel);
2418                         ret = FALSE;
2419                         break;
2420         }
2421         if (!ret)
2422                 return FALSE;
2423
2424         if (pScrn->bitsPerPixel > 8) {
2425                 /* Fixup RGB ordering */
2426                 visual = pScreen->visuals + pScreen->numVisuals;
2427                 while (--visual >= pScreen->visuals) {
2428                         if ((visual->class | DynamicClass) == DirectColor) {
2429                                 visual->offsetRed = pScrn->offset.red;
2430                                 visual->offsetGreen = pScrn->offset.green;
2431                                 visual->offsetBlue = pScrn->offset.blue;
2432                                 visual->redMask = pScrn->mask.red;
2433                                 visual->greenMask = pScrn->mask.green;
2434                                 visual->blueMask = pScrn->mask.blue;
2435                         }
2436                 }
2437         }
2438
2439         fbPictureInit (pScreen, 0, 0);
2440
2441         xf86SetBlackWhitePixels(pScreen);
2442
2443         if (!pNv->NoAccel) {
2444                 if (!NVExaInit(pScreen))
2445                         return FALSE;
2446                 NVAccelCommonInit(pScrn);
2447         } else if (pNv->VRAMPhysicalSize / 2 < NOUVEAU_ALIGN(pScrn->virtualX, 64) * NOUVEAU_ALIGN(pScrn->virtualY, 64) * (pScrn->bitsPerPixel >> 3)) {
2448                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "The virtual screen size's resolution is too big for the video RAM framebuffer at this colour depth.\n");
2449                 return FALSE;
2450         }
2451
2452
2453         miInitializeBackingStore(pScreen);
2454         xf86SetBackingStore(pScreen);
2455         xf86SetSilkenMouse(pScreen);
2456
2457         /* Finish DRI init */
2458         NVDRIFinishScreenInit(pScrn);
2459
2460         /* 
2461          * Initialize software cursor.
2462          * Must precede creation of the default colormap.
2463          */
2464         miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
2465
2466         /*
2467          * Initialize HW cursor layer. 
2468          * Must follow software cursor initialization.
2469          */
2470         if (pNv->HWCursor) { 
2471                 if (pNv->Architecture < NV_ARCH_50 && !pNv->randr12_enable)
2472                         ret = NVCursorInit(pScreen);
2473                 else if (pNv->Architecture < NV_ARCH_50 && pNv->randr12_enable)
2474                         ret = NVCursorInitRandr12(pScreen);
2475                 else
2476                         ret = NV50CursorInit(pScreen);
2477
2478                 if (ret != TRUE) {
2479                         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
2480                                 "Hardware cursor initialization failed\n");
2481                         pNv->HWCursor = FALSE;
2482                 }
2483         }
2484
2485         if (pNv->randr12_enable) {
2486                 xf86DPMSInit(pScreen, xf86DPMSSet, 0);
2487
2488                 if (!xf86CrtcScreenInit(pScreen))
2489                         return FALSE;
2490
2491                 pNv->PointerMoved = pScrn->PointerMoved;
2492                 pScrn->PointerMoved = NVPointerMoved;
2493         }
2494
2495         /* Initialise default colourmap */
2496         if (!miCreateDefColormap(pScreen))
2497                 return FALSE;
2498
2499         /*
2500          * Initialize colormap layer.
2501          * Must follow initialization of the default colormap 
2502          */
2503         if (!pNv->randr12_enable) {
2504                 if(!xf86HandleColormaps(pScreen, 256, 8, NVDACLoadPalette,
2505                                 NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
2506                 return FALSE;
2507         } else {
2508                 if (!xf86HandleColormaps(pScreen, 256, 8, NVLoadPalette,
2509                                 NULL, CMAP_PALETTED_TRUECOLOR))
2510                         return FALSE;
2511         }
2512
2513         if(pNv->ShadowFB) {
2514                 RefreshAreaFuncPtr refreshArea = NVRefreshArea;
2515
2516                 if (pNv->Rotate || pNv->RandRRotation) {
2517                         pNv->PointerMoved = pScrn->PointerMoved;
2518                         if (pNv->Rotate)
2519                                 pScrn->PointerMoved = NVPointerMoved;
2520
2521                         switch(pScrn->bitsPerPixel) {
2522                                 case 8: refreshArea = NVRefreshArea8;   break;
2523                                 case 16:        refreshArea = NVRefreshArea16;  break;
2524                                 case 32:        refreshArea = NVRefreshArea32;  break;
2525                         }
2526                         if(!pNv->RandRRotation) {
2527                                 xf86DisableRandR();
2528                                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2529                                         "Driver rotation enabled, RandR disabled\n");
2530                         }
2531                 }
2532
2533                 ShadowFBInit(pScreen, refreshArea);
2534         }
2535
2536         if (!pNv->randr12_enable) {
2537                 if(pNv->FlatPanel) {
2538                         xf86DPMSInit(pScreen, NVDPMSSetLCD, 0);
2539                 } else {
2540                         xf86DPMSInit(pScreen, NVDPMSSet, 0);
2541                 }
2542         }
2543
2544         pScrn->memPhysBase = pNv->VRAMPhysical;
2545         pScrn->fbOffset = 0;
2546
2547         if (pNv->Rotate == 0 && !pNv->RandRRotation)
2548                 NVInitVideo(pScreen);
2549
2550         pScreen->SaveScreen = NVSaveScreen;
2551
2552         /* Wrap the current CloseScreen function */
2553         pNv->CloseScreen = pScreen->CloseScreen;
2554         pScreen->CloseScreen = NVCloseScreen;
2555
2556         pNv->BlockHandler = pScreen->BlockHandler;
2557         pScreen->BlockHandler = NVBlockHandler;
2558
2559         /* Install our DriverFunc.  We have to do it this way instead of using the
2560          * HaveDriverFuncs argument to xf86AddDriver, because InitOutput clobbers
2561          * pScrn->DriverFunc 
2562          */
2563         if (!pNv->randr12_enable)
2564                 pScrn->DriverFunc = NVDriverFunc;
2565
2566         /* Report any unused options (only for the first generation) */
2567         if (serverGeneration == 1) {
2568                 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
2569         }
2570
2571         return TRUE;
2572 }
2573
2574 static Bool
2575 NVSaveScreen(ScreenPtr pScreen, int mode)
2576 {
2577     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2578     NVPtr pNv = NVPTR(pScrn);
2579     int i;
2580     Bool on = xf86IsUnblank(mode);
2581     
2582     if (pNv->randr12_enable) {
2583         xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2584         if (pScrn->vtSema && pNv->Architecture < NV_ARCH_50) {
2585             for (i = 0; i < xf86_config->num_crtc; i++) {
2586                 
2587                 if (xf86_config->crtc[i]->enabled) {
2588                     NVCrtcPrivatePtr nv_crtc = xf86_config->crtc[i]->driver_private;
2589                     NVBlankScreen(pScrn, nv_crtc->head, !on);
2590                 }
2591             }
2592             
2593         }
2594         return TRUE;
2595     }
2596
2597         return vgaHWSaveScreen(pScreen, mode);
2598 }
2599
2600 static void
2601 NVSave(ScrnInfoPtr pScrn)
2602 {
2603         NVPtr pNv = NVPTR(pScrn);
2604         NVRegPtr nvReg = &pNv->SavedReg;
2605
2606         if (pNv->randr12_enable) {
2607                 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2608                 int i;
2609
2610                 for (i = 0; i < xf86_config->num_crtc; i++) {
2611                         xf86_config->crtc[i]->funcs->save(xf86_config->crtc[i]);
2612                 }
2613
2614                 for (i = 0; i < xf86_config->num_output; i++) {
2615                         xf86_config->output[i]->funcs->save(xf86_config->
2616                                                             output[i]);
2617                 }
2618         } else {
2619                 vgaHWPtr pVga = VGAHWPTR(pScrn);
2620                 vgaRegPtr vgaReg = &pVga->SavedReg;
2621                 NVLockUnlock(pScrn, 0);
2622                 if (pNv->twoHeads) {
2623                         nvWriteCurVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->crtc_active[1] * 0x3);
2624                         NVLockUnlock(pScrn, 0);
2625                 }
2626
2627                 NVDACSave(pScrn, vgaReg, nvReg, pNv->Primary);
2628         }
2629 }
2630
2631 static Bool
2632 NVRandRGetInfo(ScrnInfoPtr pScrn, Rotation *rotations)
2633 {
2634     NVPtr pNv = NVPTR(pScrn);
2635
2636     if(pNv->RandRRotation)
2637        *rotations = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_270;
2638     else
2639        *rotations = RR_Rotate_0;
2640
2641     return TRUE;
2642 }
2643
2644 static Bool
2645 NVRandRSetConfig(ScrnInfoPtr pScrn, xorgRRConfig *config)
2646 {
2647     NVPtr pNv = NVPTR(pScrn);
2648
2649     switch(config->rotation) {
2650         case RR_Rotate_0:
2651             pNv->Rotate = 0;
2652             pScrn->PointerMoved = pNv->PointerMoved;
2653             break;
2654
2655         case RR_Rotate_90:
2656             pNv->Rotate = -1;
2657             pScrn->PointerMoved = NVPointerMoved;
2658             break;
2659
2660         case RR_Rotate_270:
2661             pNv->Rotate = 1;
2662             pScrn->PointerMoved = NVPointerMoved;
2663             break;
2664
2665         default:
2666             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2667                     "Unexpected rotation in NVRandRSetConfig!\n");
2668             pNv->Rotate = 0;
2669             pScrn->PointerMoved = pNv->PointerMoved;
2670             return FALSE;
2671     }
2672
2673     return TRUE;
2674 }
2675
2676 static Bool
2677 NVDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer data)
2678 {
2679     switch(op) {
2680        case RR_GET_INFO:
2681           return NVRandRGetInfo(pScrn, (Rotation*)data);
2682        case RR_SET_CONFIG:
2683           return NVRandRSetConfig(pScrn, (xorgRRConfig*)data);
2684        default:
2685           return FALSE;
2686     }
2687
2688     return FALSE;
2689 }