nv_driver.c revision fe196524
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#include <fcntl.h>
25
26#include "nv_include.h"
27
28#include "xorg-server.h"
29#include "xf86drm.h"
30#include "xf86drmMode.h"
31#include "nouveau_drm.h"
32#ifdef DRI2
33#include "dri2.h"
34#endif
35
36#include "nouveau_copy.h"
37#include "nouveau_present.h"
38#include "nouveau_sync.h"
39
40#if !HAVE_XORG_LIST
41#define xorg_list_is_empty              list_is_empty
42#define xorg_list_for_each_entry        list_for_each_entry
43#endif
44
45/*
46 * Forward definitions for the functions that make up the driver.
47 */
48/* Mandatory functions */
49static const OptionInfoRec * NVAvailableOptions(int chipid, int busid);
50static void    NVIdentify(int flags);
51static Bool    NVPreInit(ScrnInfoPtr pScrn, int flags);
52static Bool    NVScreenInit(SCREEN_INIT_ARGS_DECL);
53static Bool    NVEnterVT(VT_FUNC_ARGS_DECL);
54static void    NVLeaveVT(VT_FUNC_ARGS_DECL);
55static Bool    NVCloseScreen(CLOSE_SCREEN_ARGS_DECL);
56static Bool    NVSaveScreen(ScreenPtr pScreen, int mode);
57static void    NVCloseDRM(ScrnInfoPtr);
58
59/* Optional functions */
60static Bool    NVDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op,
61			    void *data);
62static Bool    NVSwitchMode(SWITCH_MODE_ARGS_DECL);
63static void    NVAdjustFrame(ADJUST_FRAME_ARGS_DECL);
64static void    NVFreeScreen(FREE_SCREEN_ARGS_DECL);
65
66/* Internally used functions */
67
68static Bool	NVMapMem(ScrnInfoPtr pScrn);
69static Bool	NVUnmapMem(ScrnInfoPtr pScrn);
70
71#define NOUVEAU_PCI_DEVICE(_vendor_id, _device_id)                             \
72	{ (_vendor_id), (_device_id), PCI_MATCH_ANY, PCI_MATCH_ANY,            \
73	  0x00030000, 0x00ff0000, 0 }
74
75static const struct pci_id_match nouveau_device_match[] = {
76	NOUVEAU_PCI_DEVICE(0x12d2, PCI_MATCH_ANY),
77	NOUVEAU_PCI_DEVICE(0x10de, PCI_MATCH_ANY),
78	{ 0, 0, 0 },
79};
80
81static Bool NVPciProbe (	DriverPtr 		drv,
82				int 			entity_num,
83				struct pci_device	*dev,
84				intptr_t		match_data	);
85
86#ifdef XSERVER_PLATFORM_BUS
87static Bool NVPlatformProbe(DriverPtr driver,
88				int entity_num, int flags,
89				struct xf86_platform_device *dev,
90				intptr_t dev_match_data);
91#endif
92
93_X_EXPORT int NVEntityIndex = -1;
94
95static int getNVEntityIndex(void)
96{
97	return NVEntityIndex;
98}
99
100/*
101 * This contains the functions needed by the server after loading the
102 * driver module.  It must be supplied, and gets added the driver list by
103 * the Module Setup funtion in the dynamic case.  In the static case a
104 * reference to this is compiled in, and this requires that the name of
105 * this DriverRec be an upper-case version of the driver name.
106 */
107
108_X_EXPORT DriverRec NV = {
109	NV_VERSION,
110	NV_DRIVER_NAME,
111	NVIdentify,
112	NULL,
113	NVAvailableOptions,
114	NULL,
115	0,
116	NVDriverFunc,
117	nouveau_device_match,
118	NVPciProbe,
119#ifdef XSERVER_PLATFORM_BUS
120	NVPlatformProbe,
121#endif
122};
123
124struct NvFamily
125{
126  char *name;
127  char *chipset;
128};
129
130static struct NvFamily NVKnownFamilies[] =
131{
132  { "RIVA TNT",    "NV04" },
133  { "RIVA TNT2",   "NV05" },
134  { "GeForce 256", "NV10" },
135  { "GeForce 2",   "NV11, NV15" },
136  { "GeForce 4MX", "NV17, NV18" },
137  { "GeForce 3",   "NV20" },
138  { "GeForce 4Ti", "NV25, NV28" },
139  { "GeForce FX",  "NV3x" },
140  { "GeForce 6",   "NV4x" },
141  { "GeForce 7",   "G7x" },
142  { "GeForce 8",   "G8x" },
143  { "GeForce GTX 200", "NVA0" },
144  { "GeForce GTX 400", "NVC0" },
145  { NULL, NULL}
146};
147
148static MODULESETUPPROTO(nouveauSetup);
149
150static XF86ModuleVersionInfo nouveauVersRec =
151{
152    "nouveau",
153    MODULEVENDORSTRING,
154    MODINFOSTRING1,
155    MODINFOSTRING2,
156    XORG_VERSION_CURRENT,
157    NV_MAJOR_VERSION, NV_MINOR_VERSION, NV_PATCHLEVEL,
158    ABI_CLASS_VIDEODRV,                     /* This is a video driver */
159    ABI_VIDEODRV_VERSION,
160    MOD_CLASS_VIDEODRV,
161    {0,0,0,0}
162};
163
164_X_EXPORT XF86ModuleData nouveauModuleData = { &nouveauVersRec, nouveauSetup, NULL };
165
166static pointer
167nouveauSetup(pointer module, pointer opts, int *errmaj, int *errmin)
168{
169	static Bool setupDone = FALSE;
170
171	/* This module should be loaded only once, but check to be sure. */
172
173	if (!setupDone) {
174		setupDone = TRUE;
175		/* The 1 here is needed to turn off a backwards compatibility mode */
176		/* Otherwise NVPciProbe() is not called */
177		xf86AddDriver(&NV, module, 1);
178
179		/*
180		 * The return value must be non-NULL on success even though there
181		 * is no TearDownProc.
182		 */
183		return (pointer)1;
184	} else {
185		if (errmaj) *errmaj = LDR_ONCEONLY;
186		return NULL;
187	}
188}
189
190static const OptionInfoRec *
191NVAvailableOptions(int chipid, int busid)
192{
193    return NVOptions;
194}
195
196/* Mandatory */
197static void
198NVIdentify(int flags)
199{
200    struct NvFamily *family;
201    size_t maxLen=0;
202
203    xf86DrvMsg(0, X_INFO, NV_NAME " driver " NV_DRIVER_DATE "\n");
204    xf86DrvMsg(0, X_INFO, NV_NAME " driver for NVIDIA chipset families :\n");
205
206    /* maximum length for alignment */
207    family = NVKnownFamilies;
208    while(family->name && family->chipset)
209    {
210        maxLen = max(maxLen, strlen(family->name));
211        family++;
212    }
213
214    /* display */
215    family = NVKnownFamilies;
216    while(family->name && family->chipset)
217    {
218        size_t len = strlen(family->name);
219        xf86ErrorF("\t%s", family->name);
220        while(len<maxLen+1)
221        {
222            xf86ErrorF(" ");
223            len++;
224        }
225        xf86ErrorF("(%s)\n", family->chipset);
226        family++;
227    }
228}
229
230static Bool
231NVDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data)
232{
233    xorgHWFlags *flag;
234
235    switch (op) {
236	case GET_REQUIRED_HW_INTERFACES:
237	    flag = (CARD32 *)data;
238	    (*flag) = 0;
239	    return TRUE;
240#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,15,99,0,0)
241	case SUPPORTS_SERVER_FDS:
242	    return TRUE;
243#endif
244	default:
245	    return FALSE;
246    }
247}
248
249static void
250NVInitScrn(ScrnInfoPtr pScrn, struct xf86_platform_device *platform_dev,
251	   int entity_num)
252{
253	DevUnion *pPriv;
254	NVEntPtr pNVEnt;
255
256	pScrn->driverVersion    = NV_VERSION;
257	pScrn->driverName       = NV_DRIVER_NAME;
258	pScrn->name             = NV_NAME;
259
260	pScrn->Probe            = NULL;
261	pScrn->PreInit          = NVPreInit;
262	pScrn->ScreenInit       = NVScreenInit;
263	pScrn->SwitchMode       = NVSwitchMode;
264	pScrn->AdjustFrame      = NVAdjustFrame;
265	pScrn->EnterVT          = NVEnterVT;
266	pScrn->LeaveVT          = NVLeaveVT;
267	pScrn->FreeScreen       = NVFreeScreen;
268
269	xf86SetEntitySharable(entity_num);
270	if (NVEntityIndex == -1)
271	    NVEntityIndex = xf86AllocateEntityPrivateIndex();
272
273	pPriv = xf86GetEntityPrivate(entity_num,
274				     NVEntityIndex);
275	if (!pPriv->ptr) {
276		pPriv->ptr = xnfcalloc(sizeof(NVEntRec), 1);
277		pNVEnt = pPriv->ptr;
278		pNVEnt->platform_dev = platform_dev;
279	}
280	else
281		pNVEnt = pPriv->ptr;
282
283	/* Reset settings which must not persist across server regeneration */
284	if (pNVEnt->reinitGeneration != serverGeneration) {
285		pNVEnt->reinitGeneration = serverGeneration;
286		/* Clear mask of assigned crtc's in this generation to "none" */
287		pNVEnt->assigned_crtcs = 0;
288	}
289
290	xf86SetEntityInstanceForScreen(pScrn, entity_num,
291					xf86GetNumEntityInstances(entity_num) - 1);
292}
293
294static struct nouveau_device *
295NVOpenNouveauDevice(struct pci_device *pci_dev,
296	struct xf86_platform_device *platform_dev, int scrnIndex, Bool probe)
297{
298	struct nouveau_device *dev = NULL;
299	char *busid;
300	int ret, fd = -1;
301
302#ifdef ODEV_ATTRIB_PATH
303	if (platform_dev)
304		busid = NULL;
305	else
306#endif
307	{
308#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,901,0)
309		XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d",
310			    pci_dev->domain, pci_dev->bus,
311			    pci_dev->dev, pci_dev->func);
312#else
313		busid = XNFprintf("pci:%04x:%02x:%02x.%d",
314				  pci_dev->domain, pci_dev->bus,
315				  pci_dev->dev, pci_dev->func);
316#endif
317	}
318
319#if defined(ODEV_ATTRIB_FD)
320	if (platform_dev)
321		fd = xf86_get_platform_device_int_attrib(platform_dev,
322							 ODEV_ATTRIB_FD, -1);
323#endif
324	if (fd != -1)
325		ret = nouveau_device_wrap(fd, 0, &dev);
326#ifdef ODEV_ATTRIB_PATH
327	else if (platform_dev) {
328		const char *path;
329
330		path = xf86_get_platform_device_attrib(platform_dev,
331						       ODEV_ATTRIB_PATH);
332
333		fd = open(path, O_RDWR | O_CLOEXEC);
334		ret = nouveau_device_wrap(fd, 1, &dev);
335		if (ret)
336			close(fd);
337	}
338#endif
339	else
340		ret = nouveau_device_open(busid, &dev);
341	if (ret)
342		xf86DrvMsg(scrnIndex, X_ERROR,
343			   "[drm] Failed to open DRM device for %s: %d\n",
344			   busid, ret);
345
346	free(busid);
347	return dev;
348}
349
350static Bool
351NVHasKMS(struct pci_device *pci_dev, struct xf86_platform_device *platform_dev)
352{
353	struct nouveau_device *dev = NULL;
354	drmVersion *version;
355	int chipset;
356
357	dev = NVOpenNouveauDevice(pci_dev, platform_dev, -1, TRUE);
358	if (!dev)
359		return FALSE;
360
361	/* Check the version reported by the kernel module.  In theory we
362	 * shouldn't have to do this, as libdrm_nouveau will do its own checks.
363	 * But, we're currently using the kernel patchlevel to also version
364	 * the DRI interface.
365	 */
366	version = drmGetVersion(dev->fd);
367	xf86DrvMsg(-1, X_INFO, "[drm] nouveau interface version: %d.%d.%d\n",
368		   version->version_major, version->version_minor,
369		   version->version_patchlevel);
370	drmFree(version);
371
372	chipset = dev->chipset;
373	nouveau_device_del(&dev);
374
375
376	switch (chipset & ~0xf) {
377	case 0x00:
378	case 0x10:
379	case 0x20:
380	case 0x30:
381	case 0x40:
382	case 0x60:
383	case 0x50:
384	case 0x80:
385	case 0x90:
386	case 0xa0:
387	case 0xc0:
388	case 0xd0:
389	case 0xe0:
390	case 0xf0:
391	case 0x100:
392	case 0x110:
393	case 0x120:
394	case 0x130:
395		break;
396	default:
397		xf86DrvMsg(-1, X_ERROR, "Unknown chipset: NV%02X\n", chipset);
398		return FALSE;
399	}
400	return TRUE;
401}
402
403static Bool
404NVPciProbe(DriverPtr drv, int entity_num, struct pci_device *pci_dev,
405	   intptr_t match_data)
406{
407	PciChipsets NVChipsets[] = {
408		{ pci_dev->device_id,
409		  (pci_dev->vendor_id << 16) | pci_dev->device_id, NULL },
410		{ -1, -1, NULL }
411	};
412	ScrnInfoPtr pScrn = NULL;
413
414	if (!NVHasKMS(pci_dev, NULL))
415		return FALSE;
416
417	pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, NVChipsets,
418				    NULL, NULL, NULL, NULL, NULL);
419	if (!pScrn)
420		return FALSE;
421
422	NVInitScrn(pScrn, NULL, entity_num);
423
424	return TRUE;
425}
426
427#ifdef XSERVER_PLATFORM_BUS
428static Bool
429NVPlatformProbe(DriverPtr driver,
430            int entity_num, int flags, struct xf86_platform_device *dev, intptr_t dev_match_data)
431{
432	ScrnInfoPtr scrn = NULL;
433	uint32_t scr_flags = 0;
434
435	if (!NVHasKMS(dev->pdev, dev))
436		return FALSE;
437
438	if (flags & PLATFORM_PROBE_GPU_SCREEN)
439		scr_flags = XF86_ALLOCATE_GPU_SCREEN;
440
441	scrn = xf86AllocateScreen(driver, scr_flags);
442	if (!scrn)
443		return FALSE;
444
445	if (xf86IsEntitySharable(entity_num))
446		xf86SetEntityShared(entity_num);
447	xf86AddEntityToScreen(scrn, entity_num);
448
449	NVInitScrn(scrn, dev, entity_num);
450
451	return TRUE;
452}
453#endif
454
455#define MAX_CHIPS MAXSCREENS
456
457Bool
458NVSwitchMode(SWITCH_MODE_ARGS_DECL)
459{
460	SCRN_INFO_PTR(arg);
461
462	return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
463}
464
465/*
466 * This function is used to initialize the Start Address - the first
467 * displayed location in the video memory.
468 */
469/* Usually mandatory */
470void
471NVAdjustFrame(ADJUST_FRAME_ARGS_DECL)
472{
473	SCRN_INFO_PTR(arg);
474	drmmode_adjust_frame(pScrn, x, y);
475}
476
477/*
478 * This is called when VT switching back to the X server.  Its job is
479 * to reinitialise the video mode.
480 */
481
482/* Mandatory */
483static Bool
484NVEnterVT(VT_FUNC_ARGS_DECL)
485{
486	SCRN_INFO_PTR(arg);
487	NVPtr pNv = NVPTR(pScrn);
488#ifdef XF86_PDEV_SERVER_FD
489	NVEntPtr pNVEnt = NVEntPriv(pScrn);
490#endif
491	int ret;
492
493	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVEnterVT is called.\n");
494
495#ifdef XF86_PDEV_SERVER_FD
496	if (!(pNVEnt->platform_dev &&
497	      (pNVEnt->platform_dev->flags & XF86_PDEV_SERVER_FD)))
498#endif
499	{
500		ret = drmSetMaster(pNv->dev->fd);
501		if (ret)
502			ErrorF("Unable to get master: %s\n", strerror(errno));
503	}
504
505	if (XF86_CRTC_CONFIG_PTR(pScrn)->num_crtc && !xf86SetDesiredModes(pScrn))
506		return FALSE;
507
508	if (pNv->overlayAdaptor && pNv->Architecture != NV_ARCH_04)
509		NV10WriteOverlayParameters(pScrn);
510
511	return TRUE;
512}
513
514/*
515 * This is called when VT switching away from the X server.  Its job is
516 * to restore the previous (text) mode.
517 */
518
519/* Mandatory */
520static void
521NVLeaveVT(VT_FUNC_ARGS_DECL)
522{
523	SCRN_INFO_PTR(arg);
524	NVPtr pNv = NVPTR(pScrn);
525#ifdef XF86_PDEV_SERVER_FD
526	NVEntPtr pNVEnt = NVEntPriv(pScrn);
527#endif
528	int ret;
529
530	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVLeaveVT is called.\n");
531
532#ifdef XF86_PDEV_SERVER_FD
533	if (pNVEnt->platform_dev &&
534	    (pNVEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
535		return;
536#endif
537
538	ret = drmDropMaster(pNv->dev->fd);
539	if (ret && errno != EIO && errno != ENODEV)
540		ErrorF("Error dropping master: %i(%m)\n", -errno);
541}
542
543static void
544NVFlushCallback(CallbackListPtr *list, pointer user_data, pointer call_data)
545{
546	ScrnInfoPtr pScrn = user_data;
547	NVPtr pNv = NVPTR(pScrn);
548	if (pScrn->vtSema && pNv->Flush)
549		pNv->Flush(pScrn);
550}
551
552#ifdef NOUVEAU_PIXMAP_SHARING
553static void
554redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
555{
556	RegionRec pixregion;
557
558	PixmapRegionInit(&pixregion, dirty->slave_dst);
559
560	DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
561#ifdef HAS_DIRTYTRACKING_ROTATION
562	PixmapSyncDirtyHelper(dirty);
563#else
564	PixmapSyncDirtyHelper(dirty, &pixregion);
565#endif
566
567	DamageRegionProcessPending(&dirty->slave_dst->drawable);
568	RegionUninit(&pixregion);
569}
570
571static void
572nouveau_dirty_update(ScreenPtr screen)
573{
574	RegionPtr region;
575	PixmapDirtyUpdatePtr ent;
576
577	if (xorg_list_is_empty(&screen->pixmap_dirty_list))
578		return;
579
580	xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
581		region = DamageRegion(ent->damage);
582		if (RegionNotEmpty(region)) {
583			redisplay_dirty(screen, ent);
584			DamageEmpty(ent->damage);
585		}
586	}
587}
588#endif
589
590static void
591NVBlockHandler (BLOCKHANDLER_ARGS_DECL)
592{
593	SCREEN_PTR(arg);
594	ScrnInfoPtr pScrn   = xf86ScreenToScrn(pScreen);
595	NVPtr pNv = NVPTR(pScrn);
596
597	pScreen->BlockHandler = pNv->BlockHandler;
598	(*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
599	pScreen->BlockHandler = NVBlockHandler;
600
601#ifdef NOUVEAU_PIXMAP_SHARING
602	nouveau_dirty_update(pScreen);
603#endif
604
605	NVFlushCallback(NULL, pScrn, NULL);
606
607	if (pNv->VideoTimerCallback)
608		(*pNv->VideoTimerCallback)(pScrn, currentTime.milliseconds);
609}
610
611static Bool
612NVCreateScreenResources(ScreenPtr pScreen)
613{
614	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
615	NVPtr pNv = NVPTR(pScrn);
616
617	pScreen->CreateScreenResources = pNv->CreateScreenResources;
618	if (!(*pScreen->CreateScreenResources)(pScreen))
619		return FALSE;
620	pScreen->CreateScreenResources = NVCreateScreenResources;
621
622	drmmode_fbcon_copy(pScreen);
623	if (!NVEnterVT(VT_FUNC_ARGS(0)))
624		return FALSE;
625
626	if (pNv->AccelMethod == EXA) {
627		PixmapPtr ppix = pScreen->GetScreenPixmap(pScreen);
628		nouveau_bo_ref(pNv->scanout, &nouveau_pixmap(ppix)->bo);
629	}
630
631	return TRUE;
632}
633
634/*
635 * This is called at the end of each server generation.  It restores the
636 * original (text) mode.  It should also unmap the video memory, and free
637 * any per-generation data allocated by the driver.  It should finish
638 * by unwrapping and calling the saved CloseScreen function.
639 */
640
641/* Mandatory */
642static Bool
643NVCloseScreen(CLOSE_SCREEN_ARGS_DECL)
644{
645	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
646	NVPtr pNv = NVPTR(pScrn);
647
648	if (XF86_CRTC_CONFIG_PTR(pScrn)->num_crtc)
649		drmmode_screen_fini(pScreen);
650
651	nouveau_present_fini(pScreen);
652	nouveau_dri2_fini(pScreen);
653	nouveau_sync_fini(pScreen);
654	nouveau_copy_fini(pScreen);
655
656	if (pScrn->vtSema) {
657		NVLeaveVT(VT_FUNC_ARGS(0));
658		pScrn->vtSema = FALSE;
659	}
660
661	NVTakedownVideo(pScrn);
662	NVAccelCommonFini(pScrn);
663	NVUnmapMem(pScrn);
664
665	xf86_cursors_fini(pScreen);
666
667	DeleteCallback(&FlushCallback, NVFlushCallback, pScrn);
668
669	if (pNv->ShadowPtr) {
670		free(pNv->ShadowPtr);
671		pNv->ShadowPtr = NULL;
672	}
673	if (pNv->overlayAdaptor) {
674		free(pNv->overlayAdaptor);
675		pNv->overlayAdaptor = NULL;
676	}
677	if (pNv->blitAdaptor) {
678		free(pNv->blitAdaptor);
679		pNv->blitAdaptor = NULL;
680	}
681	if (pNv->textureAdaptor[0]) {
682		free(pNv->textureAdaptor[0]);
683		pNv->textureAdaptor[0] = NULL;
684	}
685	if (pNv->textureAdaptor[1]) {
686		free(pNv->textureAdaptor[1]);
687		pNv->textureAdaptor[1] = NULL;
688	}
689	if (pNv->EXADriverPtr) {
690		exaDriverFini(pScreen);
691		free(pNv->EXADriverPtr);
692		pNv->EXADriverPtr = NULL;
693	}
694
695	pScrn->vtSema = FALSE;
696	pScreen->CloseScreen = pNv->CloseScreen;
697	pScreen->BlockHandler = pNv->BlockHandler;
698	return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
699}
700
701/* Free up any persistent data structures */
702
703/* Optional */
704static void
705NVFreeScreen(FREE_SCREEN_ARGS_DECL)
706{
707	/*
708	 * This only gets called when a screen is being deleted.  It does not
709	 * get called routinely at the end of a server generation.
710	 */
711	SCRN_INFO_PTR(arg);
712	NVPtr pNv = NVPTR(pScrn);
713
714	if (!pNv)
715		return;
716
717	NVCloseDRM(pScrn);
718
719	free(pScrn->driverPrivate);
720	pScrn->driverPrivate = NULL;
721}
722
723#define NVPreInitFail(fmt, args...) do {                                    \
724	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%d: "fmt, __LINE__, ##args); \
725	NVFreeScreen(FREE_SCREEN_ARGS(pScrn));			\
726	return FALSE;                                                       \
727} while(0)
728
729static void
730NVCloseDRM(ScrnInfoPtr pScrn)
731{
732	NVPtr pNv = NVPTR(pScrn);
733
734	drmFree(pNv->drm_device_name);
735	nouveau_client_del(&pNv->client);
736	nouveau_device_del(&pNv->dev);
737	free(pNv->render_node);
738}
739
740static void
741nouveau_setup_capabilities(ScrnInfoPtr pScrn)
742{
743#ifdef NOUVEAU_PIXMAP_SHARING
744	NVPtr pNv = NVPTR(pScrn);
745	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
746	uint64_t value;
747	int ret;
748
749	pScrn->capabilities = 0;
750	ret = drmGetCap(pNv->dev->fd, DRM_CAP_PRIME, &value);
751	if (ret == 0) {
752		if (value & DRM_PRIME_CAP_EXPORT)
753			pScrn->capabilities |= RR_Capability_SourceOutput;
754		if (value & DRM_PRIME_CAP_IMPORT) {
755			pScrn->capabilities |= RR_Capability_SourceOffload;
756			if (xf86_config->num_crtc)
757				pScrn->capabilities |= RR_Capability_SinkOutput;
758		}
759	}
760#endif
761}
762
763NVEntPtr NVEntPriv(ScrnInfoPtr pScrn)
764{
765	DevUnion     *pPriv;
766	NVPtr  pNv   = NVPTR(pScrn);
767	pPriv = xf86GetEntityPrivate(pNv->pEnt->index,
768				     getNVEntityIndex());
769	return pPriv->ptr;
770}
771
772static Bool NVOpenDRMMaster(ScrnInfoPtr pScrn)
773{
774	NVPtr pNv = NVPTR(pScrn);
775	NVEntPtr pNVEnt = NVEntPriv(pScrn);
776	drmSetVersion sv;
777	int err;
778	int ret;
779
780	if (pNVEnt->fd) {
781		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
782			   " reusing fd for second head\n");
783		ret = nouveau_device_wrap(pNVEnt->fd, 0, &pNv->dev);
784		if (ret) {
785			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
786				"[drm] error creating device\n");
787			return FALSE;
788		}
789		return TRUE;
790	}
791
792	pNv->dev = NVOpenNouveauDevice(pNv->PciInfo, pNVEnt->platform_dev,
793				       pScrn->scrnIndex, FALSE);
794	if (!pNv->dev)
795		return FALSE;
796
797	sv.drm_di_major = 1;
798	sv.drm_di_minor = 1;
799	sv.drm_dd_major = -1;
800	sv.drm_dd_minor = -1;
801	err = drmSetInterfaceVersion(pNv->dev->fd, &sv);
802	if (err != 0) {
803		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
804			   "[drm] failed to set drm interface version.\n");
805		nouveau_device_del(&pNv->dev);
806		return FALSE;
807	}
808	pNVEnt->fd = pNv->dev->fd;
809	return TRUE;
810}
811
812static Bool
813NVPreInitDRM(ScrnInfoPtr pScrn)
814{
815	NVPtr pNv = NVPTR(pScrn);
816	int ret;
817
818	if (!xf86LoadSubModule(pScrn, "dri2"))
819		return FALSE;
820
821	/* Load the kernel module, and open the DRM */
822	ret = NVOpenDRMMaster(pScrn);
823	if (!ret) {
824		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
825			   "[drm] error opening the drm\n");
826		return FALSE;
827	}
828
829	ret = nouveau_client_new(pNv->dev, &pNv->client);
830	if (ret)
831		return FALSE;
832
833	pNv->drm_device_name = drmGetDeviceNameFromFd(pNv->dev->fd);
834
835	return TRUE;
836}
837
838/* Mandatory */
839Bool
840NVPreInit(ScrnInfoPtr pScrn, int flags)
841{
842	struct nouveau_device *dev;
843	NVPtr pNv;
844	MessageType from;
845	const char *reason, *string;
846	uint64_t v;
847	int ret;
848	int defaultDepth = 0;
849
850	if (flags & PROBE_DETECT) {
851		EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
852
853		if (!pEnt)
854			return FALSE;
855
856		free(pEnt);
857
858		return TRUE;
859	}
860
861	/*
862	 * Note: This function is only called once at server startup, and
863	 * not at the start of each server generation.  This means that
864	 * only things that are persistent across server generations can
865	 * be initialised here.  xf86Screens[] is (pScrn is a pointer to one
866	 * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()
867	 * are too, and should be used for data that must persist across
868	 * server generations.
869	 *
870	 * Per-generation data should be allocated with
871	 * AllocateScreenPrivateIndex() from the ScreenInit() function.
872	 */
873
874	/* Check the number of entities, and fail if it isn't one. */
875	if (pScrn->numEntities != 1)
876		return FALSE;
877
878	/* Allocate the NVRec driverPrivate */
879	if (!(pScrn->driverPrivate = xnfcalloc(1, sizeof(NVRec))))
880		return FALSE;
881	pNv = NVPTR(pScrn);
882
883	/* Get the entity, and make sure it is PCI. */
884	pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
885	if (pNv->pEnt->location.type != BUS_PCI
886#ifdef XSERVER_PLATFORM_BUS
887		&& pNv->pEnt->location.type != BUS_PLATFORM
888#endif
889		)
890		return FALSE;
891
892	if (xf86IsEntityShared(pScrn->entityList[0])) {
893		if(!xf86IsPrimInitDone(pScrn->entityList[0])) {
894			pNv->Primary = TRUE;
895			xf86SetPrimInitDone(pScrn->entityList[0]);
896		} else {
897			pNv->Secondary = TRUE;
898		}
899        }
900
901	/* Find the PCI info for this screen */
902	pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index);
903
904	/* Initialise the kernel module */
905	if (!NVPreInitDRM(pScrn))
906		NVPreInitFail("\n");
907	dev = pNv->dev;
908
909	pScrn->chipset = malloc(sizeof(char) * 25);
910	sprintf((char *)pScrn->chipset, "NVIDIA NV%02X", dev->chipset);
911	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Chipset: \"%s\"\n", pScrn->chipset);
912
913	switch (dev->chipset & ~0xf) {
914	case 0x00:
915		pNv->Architecture = NV_ARCH_04;
916		break;
917	case 0x10:
918		pNv->Architecture = NV_ARCH_10;
919		break;
920	case 0x20:
921		pNv->Architecture = NV_ARCH_20;
922		break;
923	case 0x30:
924		pNv->Architecture = NV_ARCH_30;
925		break;
926	case 0x40:
927	case 0x60:
928		pNv->Architecture = NV_ARCH_40;
929		break;
930	case 0x50:
931	case 0x80:
932	case 0x90:
933	case 0xa0:
934		pNv->Architecture = NV_TESLA;
935		break;
936	case 0xc0:
937	case 0xd0:
938		pNv->Architecture = NV_FERMI;
939		break;
940	case 0xe0:
941	case 0xf0:
942	case 0x100:
943		pNv->Architecture = NV_KEPLER;
944		break;
945	case 0x110:
946	case 0x120:
947		pNv->Architecture = NV_MAXWELL;
948		break;
949	case 0x130:
950		pNv->Architecture = NV_PASCAL;
951		break;
952	default:
953		return FALSE;
954	}
955
956	/* Set pScrn->monitor */
957	pScrn->monitor = pScrn->confScreen->monitor;
958
959	/*
960	 * The first thing we should figure out is the depth, bpp, etc.
961	 */
962
963	if (dev->vram_size <= 16 * 1024 * 1024)
964		defaultDepth = 16;
965	if (!xf86SetDepthBpp(pScrn, defaultDepth, 0, 0, Support32bppFb)) {
966		NVPreInitFail("\n");
967	} else {
968		/* Check that the returned depth is one we support */
969		switch (pScrn->depth) {
970		case 16:
971		case 24:
972			/* OK */
973			break;
974		case 30:
975			/* OK on NV50 KMS */
976			if (pNv->Architecture < NV_TESLA)
977				NVPreInitFail("Depth 30 supported on G80+ only\n");
978			break;
979		case 15: /* 15 may get done one day, so leave any code for it in place */
980		default:
981			NVPreInitFail("Given depth (%d) is not supported by this driver\n",
982				pScrn->depth);
983		}
984	}
985	xf86PrintDepthBpp(pScrn);
986
987	/*
988	 * This must happen after pScrn->display has been set because
989	 * xf86SetWeight references it.
990	 */
991	rgb rgbzeros = {0, 0, 0};
992
993	if (pScrn->depth == 30) {
994		rgb rgbmask;
995
996		rgbmask.red   = 0x000003ff;
997		rgbmask.green = 0x000ffc00;
998		rgbmask.blue  = 0x3ff00000;
999		if (!xf86SetWeight(pScrn, rgbzeros, rgbmask))
1000			NVPreInitFail("\n");
1001
1002		/* xf86SetWeight() seems to think ffs(1) == 0... */
1003		pScrn->offset.red--;
1004		pScrn->offset.green--;
1005		pScrn->offset.blue--;
1006	} else {
1007		if (!xf86SetWeight(pScrn, rgbzeros, rgbzeros))
1008			NVPreInitFail("\n");
1009	}
1010
1011	if (!xf86SetDefaultVisual(pScrn, -1))
1012		NVPreInitFail("\n");
1013
1014	/* We don't support DirectColor */
1015	if (pScrn->defaultVisual != TrueColor) {
1016		NVPreInitFail("Given default visual (%s) is not supported at depth %d\n",
1017			      xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
1018	}
1019
1020	/* We use a programmable clock */
1021	pScrn->progClock = TRUE;
1022
1023	/* Collect all of the relevant option flags (fill in pScrn->options) */
1024	xf86CollectOptions(pScrn, NULL);
1025
1026	/* Process the options */
1027	if (!(pNv->Options = malloc(sizeof(NVOptions))))
1028		return FALSE;
1029	memcpy(pNv->Options, NVOptions, sizeof(NVOptions));
1030	xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options);
1031
1032	from = X_DEFAULT;
1033
1034	pNv->HWCursor = TRUE;
1035	/*
1036	 * The preferred method is to use the "hw cursor" option as a tri-state
1037	 * option, with the default set above.
1038	 */
1039	if (xf86GetOptValBool(pNv->Options, OPTION_HW_CURSOR, &pNv->HWCursor)) {
1040		from = X_CONFIG;
1041	}
1042	/* For compatibility, accept this too (as an override) */
1043	if (xf86ReturnOptValBool(pNv->Options, OPTION_SW_CURSOR, FALSE)) {
1044		from = X_CONFIG;
1045		pNv->HWCursor = FALSE;
1046	}
1047	xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
1048		pNv->HWCursor ? "HW" : "SW");
1049
1050	string = xf86GetOptValString(pNv->Options, OPTION_ACCELMETHOD);
1051	if (string) {
1052		if      (!strcmp(string,   "none")) pNv->AccelMethod = NONE;
1053		else if (!strcmp(string,    "exa")) pNv->AccelMethod = EXA;
1054		else {
1055			xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1056				   "Invalid AccelMethod specified\n");
1057		}
1058	}
1059
1060	if (pNv->AccelMethod == UNKNOWN) {
1061		pNv->AccelMethod = EXA;
1062	}
1063
1064	if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) {
1065		pNv->AccelMethod = NONE;
1066		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
1067	}
1068
1069	if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) {
1070		pNv->ShadowFB = TRUE;
1071		pNv->AccelMethod = NONE;
1072		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1073			"Using \"Shadow Framebuffer\" - acceleration disabled\n");
1074	}
1075
1076	if (pNv->AccelMethod > NONE) {
1077#if 0
1078		if (pNv->Architecture >= NV_TESLA)
1079			pNv->wfb_enabled = xf86ReturnOptValBool(
1080				pNv->Options, OPTION_WFB, FALSE);
1081#endif
1082
1083		pNv->tiled_scanout = TRUE;
1084	}
1085
1086	pNv->ce_enabled =
1087		xf86ReturnOptValBool(pNv->Options, OPTION_ASYNC_COPY, FALSE);
1088
1089	/* Define maximum allowed level of DRI implementation to use.
1090	 * We default to DRI2 on EXA for now, as DRI3 still has some
1091	 * problems.
1092	 */
1093	pNv->max_dri_level = 2;
1094	from = X_DEFAULT;
1095
1096	if (xf86GetOptValInteger(pNv->Options, OPTION_DRI,
1097				 &pNv->max_dri_level)) {
1098		from = X_CONFIG;
1099		if (pNv->max_dri_level < 2)
1100			pNv->max_dri_level = 2;
1101		if (pNv->max_dri_level > 3)
1102			pNv->max_dri_level = 3;
1103	}
1104	xf86DrvMsg(pScrn->scrnIndex, from, "Allowed maximum DRI level %i.\n",
1105		   pNv->max_dri_level);
1106
1107	if (pNv->AccelMethod > NONE && pNv->dev->chipset >= 0x11) {
1108		from = X_DEFAULT;
1109		pNv->glx_vblank = TRUE;
1110		if (xf86GetOptValBool(pNv->Options, OPTION_GLX_VBLANK,
1111				      &pNv->glx_vblank))
1112			from = X_CONFIG;
1113
1114		xf86DrvMsg(pScrn->scrnIndex, from, "GLX sync to VBlank %s.\n",
1115			   pNv->glx_vblank ? "enabled" : "disabled");
1116	}
1117
1118#ifdef NOUVEAU_GETPARAM_HAS_PAGEFLIP
1119	reason = ": no kernel support";
1120	from = X_DEFAULT;
1121
1122	ret = nouveau_getparam(pNv->dev, NOUVEAU_GETPARAM_HAS_PAGEFLIP, &v);
1123	if (ret == 0 && v == 1) {
1124		pNv->has_pageflip = TRUE;
1125		if (xf86GetOptValBool(pNv->Options, OPTION_PAGE_FLIP, &pNv->has_pageflip))
1126			from = X_CONFIG;
1127		reason = "";
1128	}
1129#else
1130	reason = ": not available at build time";
1131#endif
1132
1133	xf86DrvMsg(pScrn->scrnIndex, from, "Page flipping %sabled%s\n",
1134		   pNv->has_pageflip ? "en" : "dis", reason);
1135
1136	if(xf86GetOptValInteger(pNv->Options, OPTION_VIDEO_KEY, &(pNv->videoKey))) {
1137		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
1138					pNv->videoKey);
1139	} else {
1140		pNv->videoKey =  (1 << pScrn->offset.red) |
1141					(1 << pScrn->offset.green) |
1142		(((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue);
1143	}
1144
1145	/* Limit to max 2 pending swaps - we can't handle more than triple-buffering: */
1146	pNv->max_swap_limit = 2;
1147
1148	if(xf86GetOptValInteger(pNv->Options, OPTION_SWAP_LIMIT, &(pNv->swap_limit))) {
1149		if (pNv->swap_limit < 1)
1150			pNv->swap_limit = 1;
1151
1152		if (pNv->swap_limit > pNv->max_swap_limit)
1153			pNv->swap_limit = pNv->max_swap_limit;
1154
1155		reason = "";
1156		from = X_CONFIG;
1157
1158		if ((DRI2INFOREC_VERSION < 6) && (pNv->swap_limit > 1)) {
1159			/* No swap limit api in server. A value > 1 requires use
1160			 * of problematic hacks.
1161			 */
1162			from = X_WARNING;
1163			reason = ": Caution: Use of this swap limit > 1 violates OML_sync_control spec on this X-Server!\n";
1164		}
1165	} else {
1166		/* Always default to double-buffering, because it avoids artifacts like
1167		 * unthrottled rendering of non-fullscreen clients under desktop composition.
1168		 */
1169		pNv->swap_limit = 1;
1170		reason = "";
1171		from = X_DEFAULT;
1172	}
1173
1174	xf86DrvMsg(pScrn->scrnIndex, from, "Swap limit set to %d [Max allowed %d]%s\n",
1175		   pNv->swap_limit, pNv->max_swap_limit, reason);
1176
1177	/* Does kernel do the sync of pageflips to vblank? */
1178	pNv->has_async_pageflip = FALSE;
1179#ifdef DRM_CAP_ASYNC_PAGE_FLIP
1180	ret = drmGetCap(pNv->dev->fd, DRM_CAP_ASYNC_PAGE_FLIP, &v);
1181	if (ret == 0 && v == 1) {
1182		pNv->has_async_pageflip = TRUE;
1183	}
1184	xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Page flipping synced to vblank by %s.\n",
1185			   pNv->has_async_pageflip ? "kernel" : "ddx");
1186#endif
1187
1188	ret = drmmode_pre_init(pScrn, pNv->dev->fd, pScrn->bitsPerPixel >> 3);
1189	if (ret == FALSE)
1190		NVPreInitFail("Kernel modesetting failed to initialize\n");
1191
1192	/*
1193	 * If the driver can do gamma correction, it should call xf86SetGamma()
1194	 * here.
1195	 */
1196	Gamma gammazeros = {0.0, 0.0, 0.0};
1197
1198	if (!xf86SetGamma(pScrn, gammazeros))
1199		NVPreInitFail("\n");
1200
1201#ifdef NOUVEAU_PIXMAP_SHARING
1202	/*
1203	 * The driver will not work as gpu screen without acceleration enabled.
1204	 * To support this usecase modesetting ddx can be used instead.
1205	 */
1206	if (pNv->AccelMethod <= NONE || pNv->ShadowFB) {
1207		/*
1208		 * Optimus mode requires acceleration enabled.
1209		 * So if no mode is found, or the screen is created
1210		 * as a gpu screen the pre init should fail.
1211		 */
1212		if (pScrn->is_gpu || !pScrn->modes)
1213			return FALSE;
1214	}
1215
1216#else
1217	/* No usable mode, no optimus config possible */
1218	if (!pScrn->modes)
1219		return FALSE;
1220#endif
1221
1222	nouveau_setup_capabilities(pScrn);
1223
1224	if (!pScrn->modes) {
1225		pScrn->modes = xf86ModesAdd(pScrn->modes,
1226			xf86CVTMode(pScrn->display->virtualX,
1227				    pScrn->display->virtualY,
1228				    60, 0, 0));
1229	}
1230
1231	/* Set the current mode to the first in the list */
1232	pScrn->currentMode = pScrn->modes;
1233
1234	/* Print the list of modes being used */
1235	xf86PrintModes(pScrn);
1236
1237	/* Set display resolution */
1238	xf86SetDpi(pScrn, 0, 0);
1239
1240#if 0
1241	if (pNv->wfb_enabled) {
1242		if (xf86LoadSubModule(pScrn, "wfb") == NULL)
1243			NVPreInitFail("\n");
1244	}
1245#endif
1246
1247	if (xf86LoadSubModule(pScrn, "fb") == NULL)
1248		NVPreInitFail("\n");
1249
1250	/* Load shadowfb */
1251	if (!xf86LoadSubModule(pScrn, "shadowfb"))
1252		NVPreInitFail("\n");
1253
1254	return TRUE;
1255}
1256
1257
1258static Bool
1259NVMapMem(ScrnInfoPtr pScrn)
1260{
1261	NVPtr pNv = NVPTR(pScrn);
1262	int ret, pitch;
1263
1264	ret = nouveau_allocate_surface(pScrn, pScrn->virtualX, pScrn->virtualY,
1265				       pScrn->bitsPerPixel,
1266				       NOUVEAU_CREATE_PIXMAP_SCANOUT,
1267				       &pitch, &pNv->scanout);
1268	if (!ret) {
1269		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1270			   "Error allocating scanout buffer: %d\n", ret);
1271		return FALSE;
1272	}
1273
1274	pScrn->displayWidth = pitch / (pScrn->bitsPerPixel / 8);
1275	return TRUE;
1276}
1277
1278/*
1279 * Unmap the framebuffer and offscreen memory.
1280 */
1281
1282static Bool
1283NVUnmapMem(ScrnInfoPtr pScrn)
1284{
1285	NVPtr pNv = NVPTR(pScrn);
1286
1287	drmmode_remove_fb(pScrn);
1288
1289	nouveau_bo_ref(NULL, &pNv->transfer);
1290	nouveau_bo_ref(NULL, &pNv->scanout);
1291	return TRUE;
1292}
1293
1294static void
1295NVLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
1296	      LOCO * colors, VisualPtr pVisual)
1297{
1298	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1299	int c;
1300	int i, j, index;
1301	CARD16 lut_r[256], lut_g[256], lut_b[256];
1302
1303	for (c = 0; c < xf86_config->num_crtc; c++) {
1304		xf86CrtcPtr crtc = xf86_config->crtc[c];
1305
1306		/* code borrowed from intel driver */
1307		switch (pScrn->depth) {
1308		case 15:
1309			for (i = 0; i < numColors; i++) {
1310				index = indices[i];
1311				for (j = 0; j < 8; j++) {
1312					lut_r[index * 8 + j] = colors[index].red << 8;
1313					lut_g[index * 8 + j] = colors[index].green << 8;
1314					lut_b[index * 8 + j] = colors[index].blue << 8;
1315				}
1316			}
1317			break;
1318
1319		case 16:
1320			for (i = 0; i < numColors; i++) {
1321				index = indices[i];
1322
1323				if (i <= 31) {
1324					for (j = 0; j < 8; j++) {
1325						lut_r[index * 8 + j] = colors[index].red << 8;
1326						lut_b[index * 8 + j] = colors[index].blue << 8;
1327					}
1328				}
1329
1330				for (j = 0; j < 4; j++) {
1331					lut_g[index * 4 + j] = colors[index].green << 8;
1332				}
1333			}
1334			break;
1335
1336		default:
1337			for (i = 0; i < numColors; i++) {
1338				index = indices[i];
1339				lut_r[index] = colors[index].red << 8;
1340				lut_g[index] = colors[index].green << 8;
1341				lut_b[index] = colors[index].blue << 8;
1342			}
1343			break;
1344		}
1345
1346		if (crtc->randr_crtc)
1347			/* Make the change through RandR */
1348			RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
1349	}
1350}
1351
1352/* Mandatory */
1353
1354/* This gets called at the start of each server generation */
1355static Bool
1356NVScreenInit(SCREEN_INIT_ARGS_DECL)
1357{
1358	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1359	NVPtr pNv = NVPTR(pScrn);
1360	int ret;
1361	VisualPtr visual;
1362	unsigned char *FBStart;
1363	int displayWidth;
1364
1365	if (pNv->AccelMethod == EXA) {
1366		if (!NVAccelCommonInit(pScrn)) {
1367			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1368				   "Error initialising acceleration.  "
1369				   "Falling back to NoAccel\n");
1370			pNv->AccelMethod = NONE;
1371			pNv->ShadowFB = TRUE;
1372#if 0
1373			pNv->wfb_enabled = FALSE;
1374#endif
1375			pNv->tiled_scanout = FALSE;
1376			pScrn->displayWidth = nv_pitch_align(pNv,
1377							     pScrn->virtualX,
1378							     pScrn->depth);
1379		}
1380	}
1381
1382	nouveau_copy_init(pScreen);
1383
1384	/* Allocate and map memory areas we need */
1385	if (!NVMapMem(pScrn))
1386		return FALSE;
1387
1388	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1389	int i;
1390
1391	/* need to point to new screen on server regeneration */
1392	for (i = 0; i < xf86_config->num_crtc; i++)
1393		xf86_config->crtc[i]->scrn = pScrn;
1394	for (i = 0; i < xf86_config->num_output; i++)
1395		xf86_config->output[i]->scrn = pScrn;
1396
1397	/*
1398	 * The next step is to setup the screen's visuals, and initialise the
1399	 * framebuffer code.  In cases where the framebuffer's default
1400	 * choices for things like visual layouts and bits per RGB are OK,
1401	 * this may be as simple as calling the framebuffer's ScreenInit()
1402	 * function.  If not, the visuals will need to be setup before calling
1403	 * a fb ScreenInit() function and fixed up after.
1404	 *
1405	 * For most PC hardware at depths >= 8, the defaults that fb uses
1406	 * are not appropriate.  In this driver, we fixup the visuals after.
1407	 */
1408
1409	/*
1410	 * Reset the visual list.
1411	 */
1412	miClearVisualTypes();
1413
1414	/* Setup the visuals we support. */
1415	if (!miSetVisualTypes(pScrn->depth,
1416			      miGetDefaultVisualMask(pScrn->depth),
1417			      pScrn->rgbBits, pScrn->defaultVisual))
1418		return FALSE;
1419
1420	if (!miSetPixmapDepths ())
1421		return FALSE;
1422
1423	/*
1424	 * Call the framebuffer layer's ScreenInit function, and fill in other
1425	 * pScreen fields.
1426	 */
1427
1428	if (pNv->ShadowFB) {
1429		pNv->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * pScrn->virtualX);
1430		pNv->ShadowPtr = malloc(pNv->ShadowPitch * pScrn->virtualY);
1431		displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3);
1432		FBStart = pNv->ShadowPtr;
1433	} else
1434	if (pNv->AccelMethod <= NONE) {
1435		pNv->ShadowPtr = NULL;
1436		displayWidth = pScrn->displayWidth;
1437		nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR, pNv->client);
1438		FBStart = pNv->scanout->map;
1439	} else {
1440		pNv->ShadowPtr = NULL;
1441		displayWidth = pScrn->displayWidth;
1442		FBStart = NULL;
1443	}
1444
1445	switch (pScrn->bitsPerPixel) {
1446	case 16:
1447	case 32:
1448#if 0
1449	if (pNv->wfb_enabled) {
1450		ret = wfbScreenInit(pScreen, FBStart, pScrn->virtualX,
1451				    pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
1452				    displayWidth, pScrn->bitsPerPixel,
1453				    nouveau_wfb_setup_wrap,
1454				    nouveau_wfb_finish_wrap);
1455	} else {
1456#endif
1457		ret = fbScreenInit(pScreen, FBStart, pScrn->virtualX,
1458				   pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
1459				   displayWidth, pScrn->bitsPerPixel);
1460#if 0
1461	}
1462#endif
1463		break;
1464	default:
1465		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1466			   "Internal error: invalid bpp (%d) in NVScreenInit\n",
1467			   pScrn->bitsPerPixel);
1468		ret = FALSE;
1469		break;
1470	}
1471	if (!ret)
1472		return FALSE;
1473
1474	/* Fixup RGB ordering */
1475	visual = pScreen->visuals + pScreen->numVisuals;
1476	while (--visual >= pScreen->visuals) {
1477		if ((visual->class | DynamicClass) == DirectColor) {
1478			visual->offsetRed = pScrn->offset.red;
1479			visual->offsetGreen = pScrn->offset.green;
1480			visual->offsetBlue = pScrn->offset.blue;
1481			visual->redMask = pScrn->mask.red;
1482			visual->greenMask = pScrn->mask.green;
1483			visual->blueMask = pScrn->mask.blue;
1484		}
1485	}
1486
1487#if 0
1488	if (pNv->wfb_enabled)
1489		wfbPictureInit (pScreen, 0, 0);
1490	else
1491#endif
1492		fbPictureInit (pScreen, 0, 0);
1493
1494	xf86SetBlackWhitePixels(pScreen);
1495
1496	if (nouveau_present_init(pScreen))
1497		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1498			   "Hardware support for Present enabled\n");
1499	else
1500		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1501			   "Hardware support for Present disabled\n");
1502
1503	nouveau_sync_init(pScreen);
1504	nouveau_dri2_init(pScreen);
1505	if (pNv->AccelMethod == EXA) {
1506		if (pNv->max_dri_level >= 3 &&
1507		    !nouveau_dri3_screen_init(pScreen))
1508			return FALSE;
1509
1510		if (!nouveau_exa_init(pScreen))
1511			return FALSE;
1512	}
1513
1514	xf86SetBackingStore(pScreen);
1515	xf86SetSilkenMouse(pScreen);
1516
1517	/*
1518	 * Initialize software cursor.
1519	 * Must precede creation of the default colormap.
1520	 */
1521	miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
1522
1523	/*
1524	 * Initialize HW cursor layer.
1525	 * Must follow software cursor initialization.
1526	 */
1527	if (xf86_config->num_crtc && pNv->HWCursor) {
1528		ret = drmmode_cursor_init(pScreen);
1529		if (ret != TRUE) {
1530			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1531				   "Hardware cursor initialization failed\n");
1532			pNv->HWCursor = FALSE;
1533		}
1534	}
1535
1536	if (pNv->ShadowFB)
1537		ShadowFBInit(pScreen, NVRefreshArea);
1538
1539	pScrn->fbOffset = 0;
1540
1541	NVInitVideo(pScreen);
1542
1543	/* Wrap the block handler here, if we do it after the EnterVT we
1544	 * can end up in the unfortunate case where we've wrapped the
1545	 * xf86RotateBlockHandler which sometimes is not expecting to
1546	 * be in the wrap chain and calls a NULL pointer...
1547	 */
1548	pNv->BlockHandler = pScreen->BlockHandler;
1549	pScreen->BlockHandler = NVBlockHandler;
1550
1551	if (!AddCallback(&FlushCallback, NVFlushCallback, pScrn))
1552		return FALSE;
1553
1554	pScrn->vtSema = TRUE;
1555	pScrn->pScreen = pScreen;
1556
1557	xf86DPMSInit(pScreen, xf86DPMSSet, 0);
1558
1559	/* Wrap the current CloseScreen function */
1560	pScreen->SaveScreen = NVSaveScreen;
1561	pNv->CloseScreen = pScreen->CloseScreen;
1562	pScreen->CloseScreen = NVCloseScreen;
1563	pNv->CreateScreenResources = pScreen->CreateScreenResources;
1564	pScreen->CreateScreenResources = NVCreateScreenResources;
1565
1566#ifdef NOUVEAU_PIXMAP_SHARING
1567	pScreen->StartPixmapTracking = PixmapStartDirtyTracking;
1568	pScreen->StopPixmapTracking = PixmapStopDirtyTracking;
1569#endif
1570
1571	if (!xf86CrtcScreenInit(pScreen))
1572		return FALSE;
1573
1574	/* Initialise default colourmap */
1575	if (!miCreateDefColormap(pScreen))
1576		return FALSE;
1577
1578	/*
1579	 * Initialize colormap layer.
1580	 * Must follow initialization of the default colormap
1581	 */
1582	if (xf86_config->num_crtc &&
1583	    !xf86HandleColormaps(pScreen, 256, 8, NVLoadPalette,
1584				 NULL, CMAP_PALETTED_TRUECOLOR))
1585		return FALSE;
1586
1587	/* Report any unused options (only for the first generation) */
1588	if (serverGeneration == 1)
1589		xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
1590
1591	if (xf86_config->num_crtc)
1592		drmmode_screen_init(pScreen);
1593	else
1594		pNv->glx_vblank = FALSE;
1595	return TRUE;
1596}
1597
1598static Bool
1599NVSaveScreen(ScreenPtr pScreen, int mode)
1600{
1601	return TRUE;
1602}
1603
1604