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