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