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