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