Merge branch 'mesa_7_5_branch'
[mesa.git] / src / gallium / state_trackers / xorg / xorg_driver.c
1 /*
2 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 *
26 * Author: Alan Hourihane <alanh@tungstengraphics.com>
27 * Author: Jakob Bornecrantz <wallbraker@gmail.com>
28 *
29 */
30
31
32 #include "xorg-server.h"
33 #include "xf86.h"
34 #include "xf86_OSproc.h"
35 #include "compiler.h"
36 #include "xf86RAC.h"
37 #include "xf86PciInfo.h"
38 #include "xf86Pci.h"
39 #include "xf86Resources.h"
40 #include "mipointer.h"
41 #include "micmap.h"
42 #include <X11/extensions/randr.h>
43 #include "fb.h"
44 #include "edid.h"
45 #include "xf86i2c.h"
46 #include "xf86Crtc.h"
47 #include "miscstruct.h"
48 #include "dixstruct.h"
49 #include "xf86xv.h"
50 #include <X11/extensions/Xv.h>
51 #ifndef XSERVER_LIBPCIACCESS
52 #error "libpciaccess needed"
53 #endif
54
55 #include <pciaccess.h>
56
57 #include "pipe/p_context.h"
58 #include "xorg_tracker.h"
59 #include "xorg_winsys.h"
60
61 static void AdjustFrame(int scrnIndex, int x, int y, int flags);
62 static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen);
63 static Bool EnterVT(int scrnIndex, int flags);
64 static Bool SaveHWState(ScrnInfoPtr pScrn);
65 static Bool RestoreHWState(ScrnInfoPtr pScrn);
66
67
68 static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
69 int flags);
70 static void FreeScreen(int scrnIndex, int flags);
71 static void LeaveVT(int scrnIndex, int flags);
72 static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
73 static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
74 char **argv);
75 static Bool PreInit(ScrnInfoPtr pScrn, int flags);
76
77 typedef enum
78 {
79 OPTION_SW_CURSOR,
80 } modesettingOpts;
81
82 static const OptionInfoRec Options[] = {
83 {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
84 {-1, NULL, OPTV_NONE, {0}, FALSE}
85 };
86
87 /*
88 * Functions that might be needed
89 */
90
91 static const char *exaSymbols[] = {
92 "exaGetVersion",
93 "exaDriverInit",
94 "exaDriverFini",
95 "exaOffscreenAlloc",
96 "exaOffscreenFree",
97 "exaWaitSync",
98 NULL
99 };
100
101 static const char *fbSymbols[] = {
102 "fbPictureInit",
103 "fbScreenInit",
104 NULL
105 };
106
107 static const char *ddcSymbols[] = {
108 "xf86PrintEDID",
109 "xf86SetDDCproperties",
110 NULL
111 };
112
113 /*
114 * Exported Xorg driver functions to winsys
115 */
116
117 void
118 xorg_tracker_loader_ref_sym_lists()
119 {
120 LoaderRefSymLists(exaSymbols, fbSymbols, ddcSymbols, NULL);
121 }
122
123 const OptionInfoRec *
124 xorg_tracker_available_options(int chipid, int busid)
125 {
126 return Options;
127 }
128
129 void
130 xorg_tracker_set_functions(ScrnInfoPtr scrn)
131 {
132 scrn->PreInit = PreInit;
133 scrn->ScreenInit = ScreenInit;
134 scrn->SwitchMode = SwitchMode;
135 scrn->AdjustFrame = AdjustFrame;
136 scrn->EnterVT = EnterVT;
137 scrn->LeaveVT = LeaveVT;
138 scrn->FreeScreen = FreeScreen;
139 scrn->ValidMode = ValidMode;
140 }
141
142 /*
143 * Static Xorg funtctions
144 */
145
146 static Bool
147 GetRec(ScrnInfoPtr pScrn)
148 {
149 if (pScrn->driverPrivate)
150 return TRUE;
151
152 pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1);
153
154 return TRUE;
155 }
156
157 static void
158 FreeRec(ScrnInfoPtr pScrn)
159 {
160 if (!pScrn)
161 return;
162
163 if (!pScrn->driverPrivate)
164 return;
165
166 xfree(pScrn->driverPrivate);
167
168 pScrn->driverPrivate = NULL;
169 }
170
171 static void
172 ProbeDDC(ScrnInfoPtr pScrn, int index)
173 {
174 ConfiguredMonitor = NULL;
175 }
176
177 static Bool
178 CreateFrontBuffer(ScrnInfoPtr pScrn)
179 {
180 modesettingPtr ms = modesettingPTR(pScrn);
181 ScreenPtr pScreen = pScrn->pScreen;
182 PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
183 unsigned handle, stride;
184
185 ms->noEvict = TRUE;
186 xorg_exa_set_displayed_usage(rootPixmap);
187 pScreen->ModifyPixmapHeader(rootPixmap,
188 pScrn->virtualX, pScrn->virtualY,
189 pScrn->depth, pScrn->bitsPerPixel,
190 pScrn->displayWidth * pScrn->bitsPerPixel / 8,
191 NULL);
192 ms->noEvict = FALSE;
193
194 handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride);
195
196 drmModeAddFB(ms->fd,
197 pScrn->virtualX,
198 pScrn->virtualY,
199 pScrn->depth,
200 pScrn->bitsPerPixel,
201 stride,
202 handle,
203 &ms->fb_id);
204
205 pScrn->frameX0 = 0;
206 pScrn->frameY0 = 0;
207 AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
208
209 return TRUE;
210 }
211
212 static Bool
213 crtc_resize(ScrnInfoPtr pScrn, int width, int height)
214 {
215 modesettingPtr ms = modesettingPTR(pScrn);
216 //ScreenPtr pScreen = pScrn->pScreen;
217 //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
218 //Bool fbAccessDisabled;
219 //CARD8 *fbstart;
220
221 if (width == pScrn->virtualX && height == pScrn->virtualY)
222 return TRUE;
223
224 ErrorF("RESIZING TO %dx%d\n", width, height);
225
226 pScrn->virtualX = width;
227 pScrn->virtualY = height;
228
229 /* HW dependent - FIXME */
230 pScrn->displayWidth = pScrn->virtualX;
231
232 drmModeRmFB(ms->fd, ms->fb_id);
233
234 /* now create new frontbuffer */
235 return CreateFrontBuffer(pScrn);
236 }
237
238 static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
239 crtc_resize
240 };
241
242 static Bool
243 PreInit(ScrnInfoPtr pScrn, int flags)
244 {
245 xf86CrtcConfigPtr xf86_config;
246 modesettingPtr ms;
247 rgb defaultWeight = { 0, 0, 0 };
248 EntityInfoPtr pEnt;
249 EntPtr msEnt = NULL;
250 char *BusID;
251 int max_width, max_height;
252
253 if (pScrn->numEntities != 1)
254 return FALSE;
255
256 pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
257
258 if (flags & PROBE_DETECT) {
259 ProbeDDC(pScrn, pEnt->index);
260 return TRUE;
261 }
262
263 /* Allocate driverPrivate */
264 if (!GetRec(pScrn))
265 return FALSE;
266
267 ms = modesettingPTR(pScrn);
268 ms->SaveGeneration = -1;
269 ms->pEnt = pEnt;
270
271 pScrn->displayWidth = 640; /* default it */
272
273 if (ms->pEnt->location.type != BUS_PCI)
274 return FALSE;
275
276 ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index);
277
278 /* Allocate an entity private if necessary */
279 if (xf86IsEntityShared(pScrn->entityList[0])) {
280 FatalError("Entity");
281 #if 0
282 msEnt = xf86GetEntityPrivate(pScrn->entityList[0],
283 modesettingEntityIndex)->ptr;
284 ms->entityPrivate = msEnt;
285 #else
286 (void)msEnt;
287 #endif
288 } else
289 ms->entityPrivate = NULL;
290
291 if (xf86RegisterResources(ms->pEnt->index, NULL, ResNone)) {
292 return FALSE;
293 }
294
295 if (xf86IsEntityShared(pScrn->entityList[0])) {
296 if (xf86IsPrimInitDone(pScrn->entityList[0])) {
297 /* do something */
298 } else {
299 xf86SetPrimInitDone(pScrn->entityList[0]);
300 }
301 }
302
303 BusID = xalloc(64);
304 sprintf(BusID, "PCI:%d:%d:%d",
305 ((ms->PciInfo->domain << 8) | ms->PciInfo->bus),
306 ms->PciInfo->dev, ms->PciInfo->func
307 );
308
309 ms->api = drm_api_create();
310 ms->fd = drmOpen(NULL, BusID);
311
312 if (ms->fd < 0)
313 return FALSE;
314
315 pScrn->racMemFlags = RAC_FB | RAC_COLORMAP;
316 pScrn->monitor = pScrn->confScreen->monitor;
317 pScrn->progClock = TRUE;
318 pScrn->rgbBits = 8;
319
320 if (!xf86SetDepthBpp
321 (pScrn, 0, 0, 0,
322 PreferConvert24to32 | SupportConvert24to32 | Support32bppFb))
323 return FALSE;
324
325 switch (pScrn->depth) {
326 case 15:
327 case 16:
328 case 24:
329 break;
330 default:
331 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
332 "Given depth (%d) is not supported by the driver\n",
333 pScrn->depth);
334 return FALSE;
335 }
336 xf86PrintDepthBpp(pScrn);
337
338 if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight))
339 return FALSE;
340 if (!xf86SetDefaultVisual(pScrn, -1))
341 return FALSE;
342
343 /* Process the options */
344 xf86CollectOptions(pScrn, NULL);
345 if (!(ms->Options = xalloc(sizeof(Options))))
346 return FALSE;
347 memcpy(ms->Options, Options, sizeof(Options));
348 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options);
349
350 /* Allocate an xf86CrtcConfig */
351 xf86CrtcConfigInit(pScrn, &crtc_config_funcs);
352 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
353
354 max_width = 8192;
355 max_height = 8192;
356 xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height);
357
358 if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) {
359 ms->SWCursor = TRUE;
360 }
361
362 SaveHWState(pScrn);
363
364 crtc_init(pScrn);
365 output_init(pScrn);
366
367 if (!xf86InitialConfiguration(pScrn, TRUE)) {
368 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
369 RestoreHWState(pScrn);
370 return FALSE;
371 }
372
373 RestoreHWState(pScrn);
374
375 /*
376 * If the driver can do gamma correction, it should call xf86SetGamma() here.
377 */
378 {
379 Gamma zeros = { 0.0, 0.0, 0.0 };
380
381 if (!xf86SetGamma(pScrn, zeros)) {
382 return FALSE;
383 }
384 }
385
386 if (pScrn->modes == NULL) {
387 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
388 return FALSE;
389 }
390
391 pScrn->currentMode = pScrn->modes;
392
393 /* Set display resolution */
394 xf86SetDpi(pScrn, 0, 0);
395
396 /* Load the required sub modules */
397 if (!xf86LoadSubModule(pScrn, "fb")) {
398 return FALSE;
399 }
400
401 xf86LoaderReqSymLists(fbSymbols, NULL);
402
403 xf86LoadSubModule(pScrn, "exa");
404
405 #ifdef DRI2
406 xf86LoadSubModule(pScrn, "dri2");
407 #endif
408
409 return TRUE;
410 }
411
412 static Bool
413 SaveHWState(ScrnInfoPtr pScrn)
414 {
415 /*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/
416
417 return TRUE;
418 }
419
420 static Bool
421 RestoreHWState(ScrnInfoPtr pScrn)
422 {
423 /*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/
424
425 return TRUE;
426 }
427
428 static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
429 pointer pReadmask)
430 {
431 ScreenPtr pScreen = screenInfo.screens[i];
432 modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
433
434 pScreen->BlockHandler = ms->blockHandler;
435 pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
436 pScreen->BlockHandler = xorgBlockHandler;
437
438 ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
439
440 #ifdef DRM_MODE_FEATURE_DIRTYFB
441 {
442 RegionPtr dirty = DamageRegion(ms->damage);
443 unsigned num_cliprects = REGION_NUM_RECTS(dirty);
444
445 if (num_cliprects) {
446 drmModeClip *clip = alloca(num_cliprects * sizeof(drmModeClip));
447 BoxPtr rect = REGION_RECTS(dirty);
448 int i;
449
450 for (i = 0; i < num_cliprects; i++, rect++) {
451 clip[i].x = rect->x1;
452 clip[i].y = rect->y1;
453 clip[i].width = rect->x2 - rect->x1;
454 clip[i].height = rect->y2 - rect->y1;
455 }
456
457 /* TODO query connector property to see if this is needed */
458 drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
459
460 DamageEmpty(ms->damage);
461 }
462 }
463 #endif
464 }
465
466 static Bool
467 CreateScreenResources(ScreenPtr pScreen)
468 {
469 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
470 modesettingPtr ms = modesettingPTR(pScrn);
471 PixmapPtr rootPixmap;
472 Bool ret;
473 unsigned handle, stride;
474
475 ms->noEvict = TRUE;
476
477 pScreen->CreateScreenResources = ms->createScreenResources;
478 ret = pScreen->CreateScreenResources(pScreen);
479 pScreen->CreateScreenResources = CreateScreenResources;
480
481 rootPixmap = pScreen->GetScreenPixmap(pScreen);
482
483 xorg_exa_set_displayed_usage(rootPixmap);
484 xorg_exa_set_shared_usage(rootPixmap);
485 if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
486 FatalError("Couldn't adjust screen pixmap\n");
487
488 ms->noEvict = FALSE;
489
490 handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride);
491
492 drmModeAddFB(ms->fd,
493 pScrn->virtualX,
494 pScrn->virtualY,
495 pScrn->depth,
496 pScrn->bitsPerPixel,
497 stride,
498 handle,
499 &ms->fb_id);
500
501 AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
502
503 #ifdef DRM_MODE_FEATURE_DIRTYFB
504 ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
505 pScreen, rootPixmap);
506
507 if (ms->damage) {
508 DamageRegister(&rootPixmap->drawable, ms->damage);
509
510 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
511 } else {
512 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
513 "Failed to create screen damage record\n");
514 return FALSE;
515 }
516 #endif
517
518 return ret;
519 }
520
521 static Bool
522 ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
523 {
524 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
525 modesettingPtr ms = modesettingPTR(pScrn);
526 VisualPtr visual;
527
528 /* deal with server regeneration */
529 if (ms->fd < 0) {
530 char *BusID;
531
532 BusID = xalloc(64);
533 sprintf(BusID, "PCI:%d:%d:%d",
534 ((ms->PciInfo->domain << 8) | ms->PciInfo->bus),
535 ms->PciInfo->dev, ms->PciInfo->func
536 );
537
538 ms->fd = drmOpen(NULL, BusID);
539
540 if (ms->fd < 0)
541 return FALSE;
542 }
543
544 if (!ms->screen) {
545 ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
546
547 if (!ms->screen) {
548 FatalError("Could not init pipe_screen\n");
549 return FALSE;
550 }
551 }
552
553 pScrn->pScreen = pScreen;
554
555 /* HW dependent - FIXME */
556 pScrn->displayWidth = pScrn->virtualX;
557
558 miClearVisualTypes();
559
560 if (!miSetVisualTypes(pScrn->depth,
561 miGetDefaultVisualMask(pScrn->depth),
562 pScrn->rgbBits, pScrn->defaultVisual))
563 return FALSE;
564
565 if (!miSetPixmapDepths())
566 return FALSE;
567
568 pScrn->memPhysBase = 0;
569 pScrn->fbOffset = 0;
570
571 if (!fbScreenInit(pScreen, NULL,
572 pScrn->virtualX, pScrn->virtualY,
573 pScrn->xDpi, pScrn->yDpi,
574 pScrn->displayWidth, pScrn->bitsPerPixel))
575 return FALSE;
576
577 if (pScrn->bitsPerPixel > 8) {
578 /* Fixup RGB ordering */
579 visual = pScreen->visuals + pScreen->numVisuals;
580 while (--visual >= pScreen->visuals) {
581 if ((visual->class | DynamicClass) == DirectColor) {
582 visual->offsetRed = pScrn->offset.red;
583 visual->offsetGreen = pScrn->offset.green;
584 visual->offsetBlue = pScrn->offset.blue;
585 visual->redMask = pScrn->mask.red;
586 visual->greenMask = pScrn->mask.green;
587 visual->blueMask = pScrn->mask.blue;
588 }
589 }
590 }
591
592 fbPictureInit(pScreen, NULL, 0);
593
594 ms->blockHandler = pScreen->BlockHandler;
595 pScreen->BlockHandler = xorgBlockHandler;
596 ms->createScreenResources = pScreen->CreateScreenResources;
597 pScreen->CreateScreenResources = CreateScreenResources;
598
599 xf86SetBlackWhitePixels(pScreen);
600
601 ms->exa = xorg_exa_init(pScrn);
602
603 miInitializeBackingStore(pScreen);
604 xf86SetBackingStore(pScreen);
605 xf86SetSilkenMouse(pScreen);
606 miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
607
608 /* Need to extend HWcursor support to handle mask interleave */
609 if (!ms->SWCursor)
610 xf86_cursors_init(pScreen, 64, 64,
611 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
612 HARDWARE_CURSOR_ARGB);
613
614 /* Must force it before EnterVT, so we are in control of VT and
615 * later memory should be bound when allocating, e.g rotate_mem */
616 pScrn->vtSema = TRUE;
617
618 pScreen->SaveScreen = xf86SaveScreen;
619 ms->CloseScreen = pScreen->CloseScreen;
620 pScreen->CloseScreen = CloseScreen;
621
622 if (!xf86CrtcScreenInit(pScreen))
623 return FALSE;
624
625 if (!miCreateDefColormap(pScreen))
626 return FALSE;
627
628 xf86DPMSInit(pScreen, xf86DPMSSet, 0);
629
630 if (serverGeneration == 1)
631 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
632
633 #if 1
634 #ifdef DRI2
635 driScreenInit(pScreen);
636 #endif
637 #endif
638
639 return EnterVT(scrnIndex, 1);
640 }
641
642 static void
643 AdjustFrame(int scrnIndex, int x, int y, int flags)
644 {
645 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
646 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
647 xf86OutputPtr output = config->output[config->compat_output];
648 xf86CrtcPtr crtc = output->crtc;
649
650 if (crtc && crtc->enabled) {
651 crtc->funcs->mode_set(crtc, pScrn->currentMode, pScrn->currentMode, x,
652 y);
653 crtc->x = output->initial_x + x;
654 crtc->y = output->initial_y + y;
655 }
656 }
657
658 static void
659 FreeScreen(int scrnIndex, int flags)
660 {
661 FreeRec(xf86Screens[scrnIndex]);
662 }
663
664 static void
665 LeaveVT(int scrnIndex, int flags)
666 {
667 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
668 modesettingPtr ms = modesettingPTR(pScrn);
669 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
670 int o;
671
672 for (o = 0; o < config->num_crtc; o++) {
673 xf86CrtcPtr crtc = config->crtc[o];
674
675 crtc_cursor_destroy(crtc);
676
677 if (crtc->rotatedPixmap || crtc->rotatedData) {
678 crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
679 crtc->rotatedData);
680 crtc->rotatedPixmap = NULL;
681 crtc->rotatedData = NULL;
682 }
683 }
684
685 drmModeRmFB(ms->fd, ms->fb_id);
686
687 RestoreHWState(pScrn);
688
689 if (drmDropMaster(ms->fd))
690 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
691 "drmDropMaster failed: %s\n", strerror(errno));
692
693 pScrn->vtSema = FALSE;
694 }
695
696 /*
697 * This gets called when gaining control of the VT, and from ScreenInit().
698 */
699 static Bool
700 EnterVT(int scrnIndex, int flags)
701 {
702 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
703 modesettingPtr ms = modesettingPTR(pScrn);
704
705 if (drmSetMaster(ms->fd)) {
706 if (errno == EINVAL) {
707 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
708 "drmSetMaster failed: 2.6.29 or newer kernel required for "
709 "multi-server DRI\n");
710 } else {
711 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
712 "drmSetMaster failed: %s\n", strerror(errno));
713 }
714 }
715
716 /*
717 * Only save state once per server generation since that's what most
718 * drivers do. Could change this to save state at each VT enter.
719 */
720 if (ms->SaveGeneration != serverGeneration) {
721 ms->SaveGeneration = serverGeneration;
722 SaveHWState(pScrn);
723 }
724
725 if (!flags) /* signals startup as we'll do this in CreateScreenResources */
726 CreateFrontBuffer(pScrn);
727
728 if (!xf86SetDesiredModes(pScrn))
729 return FALSE;
730
731 return TRUE;
732 }
733
734 static Bool
735 SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
736 {
737 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
738
739 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
740 }
741
742 static Bool
743 CloseScreen(int scrnIndex, ScreenPtr pScreen)
744 {
745 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
746 modesettingPtr ms = modesettingPTR(pScrn);
747
748 if (pScrn->vtSema) {
749 LeaveVT(scrnIndex, 0);
750 }
751 #ifdef DRI2
752 driCloseScreen(pScreen);
753 #endif
754
755 pScreen->BlockHandler = ms->blockHandler;
756 pScreen->CreateScreenResources = ms->createScreenResources;
757
758 #ifdef DRM_MODE_FEATURE_DIRTYFB
759 if (ms->damage) {
760 DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage);
761 DamageDestroy(ms->damage);
762 ms->damage = NULL;
763 }
764 #endif
765
766 if (ms->exa)
767 xorg_exa_close(pScrn);
768
769 ms->api->destroy(ms->api);
770 ms->api = NULL;
771 drmClose(ms->fd);
772 ms->fd = -1;
773
774 pScrn->vtSema = FALSE;
775 pScreen->CloseScreen = ms->CloseScreen;
776 return (*pScreen->CloseScreen) (scrnIndex, pScreen);
777 }
778
779 static ModeStatus
780 ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
781 {
782 return MODE_OK;
783 }
784
785 /* vim: set sw=4 ts=8 sts=4: */