1 /**************************************************************************
2
3 Copyright 2001 VA Linux Systems Inc., Fremont, California.
4 Copyright © 2002 by David Dawes
5
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
17 Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30 * Authors: Jeff Hartmann <jhartmann@valinux.com>
31 * Abraham van der Merwe <abraham@2d3d.co.za>
32 * David Dawes <dawes@xfree86.org>
33 * Alan Hourihane <alanh@tungstengraphics.com>
34 */
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include <string.h>
41 #include <stdio.h>
42 #include <unistd.h>
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <errno.h>
46
47 #include "sna.h"
48 #include "sna_module.h"
49 #include "sna_video.h"
50
51 #include "intel_driver.h"
52 #include "intel_options.h"
53
54 #include <xf86cmap.h>
55 #include <xf86drm.h>
56 #include <xf86RandR12.h>
57 #include <mi.h>
58 #include <micmap.h>
59
60 #if defined(HAVE_X11_EXTENSIONS_DPMSCONST_H)
61 #include <X11/extensions/dpmsconst.h>
62 #else
63 #define DPMSModeOn 0
64 #define DPMSModeOff 3
65 #endif
66
67 #include <sys/ioctl.h>
68 #include <sys/fcntl.h>
69 #include <sys/poll.h>
70 #include "i915_drm.h"
71
72 #ifdef HAVE_VALGRIND
73 #include <valgrind.h>
74 #include <memcheck.h>
75 #endif
76
77 #if HAVE_DOT_GIT
78 #include "git_version.h"
79 #else
80 #define git_version "not compiled from git"
81 #endif
82
83 #ifdef TEARFREE
84 #define ENABLE_TEAR_FREE TRUE
85 #else
86 #define ENABLE_TEAR_FREE FALSE
87 #endif
88
89 DevPrivateKeyRec sna_pixmap_key;
90 DevPrivateKeyRec sna_gc_key;
91 DevPrivateKeyRec sna_window_key;
92 DevPrivateKeyRec sna_glyph_key;
93 DevPrivateKeyRec sna_client_key;
94
95 static void
sna_load_palette(ScrnInfoPtr scrn,int numColors,int * indices,LOCO * colors,VisualPtr pVisual)96 sna_load_palette(ScrnInfoPtr scrn, int numColors, int *indices,
97 LOCO * colors, VisualPtr pVisual)
98 {
99 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
100 int p, n, i, j;
101 uint16_t lut_r[256], lut_g[256], lut_b[256];
102
103 DBG(("%s\n", __FUNCTION__));
104
105 for (p = 0; p < xf86_config->num_crtc; p++) {
106 xf86CrtcPtr crtc = xf86_config->crtc[p];
107
108 #define C(I,RGB) (colors[I].RGB << 8 | colors[I].RGB)
109 switch (scrn->depth) {
110 case 15:
111 for (n = 0; n < numColors; n++) {
112 i = indices[n];
113 for (j = 0; j < 8; j++) {
114 lut_r[8*i + j] = C(i, red);
115 lut_g[8*i + j] = C(i, green);
116 lut_b[8*i + j] = C(i, blue);
117 }
118 }
119 break;
120 case 16:
121 for (n = 0; n < numColors; n++) {
122 i = indices[n];
123
124 if (i <= 31) {
125 for (j = 0; j < 8; j++) {
126 lut_r[8*i + j] = C(i, red);
127 lut_b[8*i + j] = C(i, blue);
128 }
129 }
130
131 for (j = 0; j < 4; j++)
132 lut_g[4*i + j] = C(i, green);
133 }
134 break;
135 default:
136 for (n = 0; n < numColors; n++) {
137 i = indices[n];
138 lut_r[i] = C(i, red);
139 lut_g[i] = C(i, green);
140 lut_b[i] = C(i, blue);
141 }
142 break;
143 }
144 #undef C
145
146 /* Make the change through RandR */
147 #ifdef RANDR_12_INTERFACE
148 RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
149 #else
150 crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
151 #endif
152 }
153 }
154
155 static void
sna_set_fallback_mode(ScrnInfoPtr scrn)156 sna_set_fallback_mode(ScrnInfoPtr scrn)
157 {
158 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
159 xf86OutputPtr output = NULL;
160 xf86CrtcPtr crtc = NULL;
161 int n;
162
163 if ((unsigned)config->compat_output < config->num_output) {
164 output = config->output[config->compat_output];
165 crtc = output->crtc;
166 }
167
168 for (n = 0; n < config->num_output; n++)
169 config->output[n]->crtc = NULL;
170 for (n = 0; n < config->num_crtc; n++)
171 config->crtc[n]->enabled = FALSE;
172
173 if (output && crtc) {
174 DisplayModePtr mode;
175
176 output->crtc = crtc;
177
178 mode = xf86OutputFindClosestMode(output, scrn->currentMode);
179 if (mode &&
180 xf86CrtcSetModeTransform(crtc, mode, RR_Rotate_0, NULL, 0, 0)) {
181 crtc->desiredMode = *mode;
182 crtc->desiredMode.prev = crtc->desiredMode.next = NULL;
183 crtc->desiredMode.name = NULL;
184 crtc->desiredMode.PrivSize = 0;
185 crtc->desiredMode.PrivFlags = 0;
186 crtc->desiredMode.Private = NULL;
187 crtc->desiredRotation = RR_Rotate_0;
188 crtc->desiredTransformPresent = FALSE;
189 crtc->desiredX = 0;
190 crtc->desiredY = 0;
191 crtc->enabled = TRUE;
192 }
193 }
194
195 xf86DisableUnusedFunctions(scrn);
196 #ifdef RANDR_12_INTERFACE
197 if (get_root_window(xf86ScrnToScreen(scrn)))
198 xf86RandR12TellChanged(xf86ScrnToScreen(scrn));
199 #endif
200 }
201
sna_set_desired_mode(struct sna * sna)202 static void sna_set_desired_mode(struct sna *sna)
203 {
204 ScrnInfoPtr scrn = sna->scrn;
205
206 DBG(("%s\n", __FUNCTION__));
207
208 if (!xf86SetDesiredModes(scrn)) {
209 xf86DrvMsg(scrn->scrnIndex, X_WARNING,
210 "failed to restore desired modes on VT switch\n");
211 sna_set_fallback_mode(scrn);
212 }
213
214 sna_mode_check(sna);
215 }
216
217 /**
218 * Adjust the screen pixmap for the current location of the front buffer.
219 * This is done at EnterVT when buffers are bound as long as the resources
220 * have already been created, but the first EnterVT happens before
221 * CreateScreenResources.
222 */
sna_create_screen_resources(ScreenPtr screen)223 static Bool sna_create_screen_resources(ScreenPtr screen)
224 {
225 struct sna *sna = to_sna_from_screen(screen);
226 PixmapPtr new_front;
227 unsigned hint;
228
229 DBG(("%s(%dx%d@%d)\n", __FUNCTION__,
230 screen->width, screen->height, screen->rootDepth));
231
232 assert(sna->scrn == xf86ScreenToScrn(screen));
233 assert(to_screen_from_sna(sna) == screen);
234
235 /* free the data used during miInitScreen */
236 free(screen->devPrivate);
237 screen->devPrivate = NULL;
238
239 sna_accel_create(sna);
240
241 hint = SNA_CREATE_FB;
242 if (sna->flags & SNA_IS_HOSTED)
243 hint = 0;
244
245 new_front = screen->CreatePixmap(screen,
246 screen->width,
247 screen->height,
248 screen->rootDepth,
249 hint);
250 if (!new_front) {
251 xf86DrvMsg(screen->myNum, X_ERROR,
252 "[intel] Unable to create front buffer %dx%d at depth %d\n",
253 screen->width,
254 screen->height,
255 screen->rootDepth);
256
257 return FALSE;
258 }
259
260 /* Prefer to use the GPU for rendering into the eventual scanout
261 * bo so that we do not unduly stall when it is time to attach
262 * it to the CRTCs.
263 */
264 (void)sna_pixmap_force_to_gpu(new_front, MOVE_READ | __MOVE_SCANOUT);
265
266 screen->SetScreenPixmap(new_front);
267 assert(screen->GetScreenPixmap(screen) == new_front);
268 assert(sna->front == new_front);
269 screen->DestroyPixmap(new_front); /* transfer ownership to screen */
270
271 sna_mode_set_primary(sna);
272
273 /* Try to become master and copy the current fbcon before the
274 * actual VT switch. If we fail here, we will try to reset the
275 * mode in the eventual VT switch. This can fail if systemd has
276 * already revoked our KMS privileges, so just carry on regardless,
277 * and hope that everything is sorted after the VT switch.
278 */
279 if (intel_get_master(sna->dev) == 0) {
280 /* Only preserve the fbcon, not any subsequent server regens */
281 if (serverGeneration == 1 && (sna->flags & SNA_IS_HOSTED) == 0)
282 sna_copy_fbcon(sna);
283
284 sna_set_desired_mode(sna);
285 }
286
287 return TRUE;
288 }
289
sna_dpms_set(ScrnInfoPtr scrn,int mode,int flags)290 static void sna_dpms_set(ScrnInfoPtr scrn, int mode, int flags)
291 {
292 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
293 struct sna *sna = to_sna(scrn);
294 bool changed = false;
295 int i;
296
297 DBG(("%s(mode=%d, flags=%d), vtSema=%d => off?=%d\n",
298 __FUNCTION__, mode, flags, scrn->vtSema, mode!=DPMSModeOn));
299 if (!scrn->vtSema)
300 return;
301
302 /* Opencoded version of xf86DPMSSet().
303 *
304 * The principle difference is to skip calling crtc->dpms() when
305 * turning off the display. This (on recent enough kernels at
306 * least) should be equivalent in power consumption, but require
307 * less work (hence quicker and less likely to fail) when switching
308 * back on.
309 */
310 if (mode != DPMSModeOn) {
311 if (sna->mode.hidden == 0 && !(sna->flags & SNA_NO_DPMS)) {
312 DBG(("%s: hiding %d outputs\n",
313 __FUNCTION__, config->num_output));
314 for (i = 0; i < config->num_output; i++) {
315 xf86OutputPtr output = config->output[i];
316 if (output->crtc != NULL)
317 output->funcs->dpms(output, mode);
318 }
319 sna->mode.hidden = sna->mode.front_active + 1;
320 sna->mode.front_active = 0;
321 changed = true;
322 }
323 } else {
324 /* Re-enable CRTC that have been forced off via other means */
325 if (sna->mode.hidden != 0) {
326 DBG(("%s: unhiding %d crtc, %d outputs\n",
327 __FUNCTION__, config->num_crtc, config->num_output));
328 sna->mode.front_active = sna->mode.hidden - 1;
329 sna->mode.hidden = 0;
330 for (i = 0; i < config->num_crtc; i++) {
331 xf86CrtcPtr crtc = config->crtc[i];
332 if (crtc->enabled)
333 crtc->funcs->dpms(crtc, mode);
334 }
335
336 for (i = 0; i < config->num_output; i++) {
337 xf86OutputPtr output = config->output[i];
338 if (output->crtc != NULL)
339 output->funcs->dpms(output, mode);
340 }
341 changed = true;
342 }
343 }
344
345 DBG(("%s: hiding outputs? %d, front active? %d, changed? %d\n",
346 __FUNCTION__, sna->mode.hidden, sna->mode.front_active, changed));
347
348 if (changed)
349 sna_crtc_config_notify(xf86ScrnToScreen(scrn));
350 }
351
sna_save_screen(ScreenPtr screen,int mode)352 static Bool sna_save_screen(ScreenPtr screen, int mode)
353 {
354 ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
355
356 DBG(("%s(mode=%d [unblank=%d])\n",
357 __FUNCTION__, mode, xf86IsUnblank(mode)));
358
359 /* We have to unroll xf86SaveScreen() here as it is called
360 * by DPMSSet() nullifying our special handling crtc->dpms()
361 * in sna_dpms_set().
362 */
363 sna_dpms_set(scrn,
364 xf86IsUnblank(mode) ? DPMSModeOn : DPMSModeOff,
365 0);
366 return TRUE;
367 }
368
sna_selftest(void)369 static void sna_selftest(void)
370 {
371 sna_damage_selftest();
372 }
373
has_vsync(struct sna * sna)374 static bool has_vsync(struct sna *sna)
375 {
376 if (sna->flags & SNA_IS_HOSTED)
377 return false;
378
379 return true;
380 }
381
sna_setup_capabilities(ScrnInfoPtr scrn,int fd)382 static void sna_setup_capabilities(ScrnInfoPtr scrn, int fd)
383 {
384 #if HAS_PIXMAP_SHARING && defined(DRM_CAP_PRIME)
385 uint64_t value;
386
387 scrn->capabilities = 0;
388 if (drmGetCap(fd, DRM_CAP_PRIME, &value) == 0) {
389 if (value & DRM_PRIME_CAP_EXPORT)
390 scrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SinkOffload;
391 if (value & DRM_PRIME_CAP_IMPORT)
392 scrn->capabilities |= RR_Capability_SinkOutput;
393 }
394 #endif
395 }
396
fb_supports_depth(int fd,int depth)397 static Bool fb_supports_depth(int fd, int depth)
398 {
399 struct drm_i915_gem_create create;
400 struct drm_mode_fb_cmd fb;
401 struct drm_mode_card_res res;
402 Bool ret;
403
404 memset(&res, 0, sizeof(res));
405 (void)drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
406 if (res.count_crtcs == 0)
407 return TRUE;
408
409 VG_CLEAR(create);
410 create.handle = 0;
411 create.size = 4096;
412 if (drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create))
413 return FALSE;
414
415 VG_CLEAR(fb);
416 fb.width = 64;
417 fb.height = 16;
418 fb.pitch = 256;
419 fb.bpp = depth <= 8 ? 8 : depth <= 16 ? 16 : 32;
420 fb.depth = depth;
421 fb.handle = create.handle;
422
423 ret = drmIoctl(fd, DRM_IOCTL_MODE_ADDFB, &fb) == 0;
424 drmModeRmFB(fd, fb.fb_id);
425
426 (void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &create.handle);
427
428 return ret;
429 }
430
setup_dri(struct sna * sna)431 static void setup_dri(struct sna *sna)
432 {
433 unsigned level;
434
435 sna->dri2.available = false;
436 sna->dri2.enable = false;
437 sna->dri3.available = false;
438 sna->dri3.enable = false;
439 sna->dri3.override = false;
440
441 level = intel_option_cast_to_unsigned(sna->Options, OPTION_DRI, DEFAULT_DRI_LEVEL);
442 #if HAVE_DRI3
443 sna->dri3.available = !!xf86LoadSubModule(sna->scrn, "dri3");
444 sna->dri3.override =
445 !sna->dri3.available ||
446 xf86IsOptionSet(sna->Options, OPTION_DRI);
447 if (level >= 3 && sna->kgem.gen >= 040)
448 sna->dri3.enable = sna->dri3.available;
449 #endif
450 #if HAVE_DRI2
451 sna->dri2.available = !!xf86LoadSubModule(sna->scrn, "dri2");
452 if (level >= 2)
453 sna->dri2.enable = sna->dri2.available;
454 #endif
455 }
456
enable_tear_free(struct sna * sna)457 static bool enable_tear_free(struct sna *sna)
458 {
459 if (sna->flags & SNA_LINEAR_FB)
460 return false;
461
462 /*
463 * On recent HW, where the display surfaces are in a seperate GTT
464 * to userspace, there is much less contention on global resources
465 * and also we can assume there is much more memory bandwidth
466 * available (i.e. gen8+). This HW should rarely be under such
467 * constaints as to need to disable TearFree, so enable by default.
468 */
469 if (sna->kgem.has_full_ppgtt)
470 return true;
471
472 /*
473 * Under certain conditions, we should enable TearFree by default,
474 * for example when the hardware requires pageflipping to run within
475 * its power/performance budget.
476 */
477 if (sna_mode_wants_tear_free(sna))
478 return true;
479
480 return ENABLE_TEAR_FREE;
481 }
482
setup_tear_free(struct sna * sna)483 static bool setup_tear_free(struct sna *sna)
484 {
485 MessageType from;
486 Bool enable;
487
488 if (sna->flags & SNA_LINEAR_FB)
489 return false;
490
491 if ((sna->flags & SNA_HAS_FLIP) == 0) {
492 from = X_PROBED;
493 goto done;
494 }
495
496 if (!xf86GetOptValBool(sna->Options, OPTION_TEAR_FREE, &enable)) {
497 enable = enable_tear_free(sna);
498 from = X_DEFAULT;
499 } else
500 from = X_CONFIG;
501
502 if (enable)
503 sna->flags |= SNA_WANT_TEAR_FREE | SNA_TEAR_FREE;
504
505 done:
506 xf86DrvMsg(sna->scrn->scrnIndex, from, "TearFree %sabled\n",
507 sna->flags & SNA_TEAR_FREE ? "en" : "dis");
508 return sna->flags & SNA_TEAR_FREE;
509 }
510
511 /**
512 * This is called before ScreenInit to do any require probing of screen
513 * configuration.
514 *
515 * This code generally covers probing, module loading, option handling
516 * card mapping, and RandR setup.
517 *
518 * Since xf86InitialConfiguration ends up requiring that we set video modes
519 * in order to detect configuration, we end up having to do a lot of driver
520 * setup (talking to the DRM, mapping the device, etc.) in this function.
521 * As a result, we want to set up that server initialization once rather
522 * that doing it per generation.
523 */
sna_pre_init(ScrnInfoPtr scrn,int probe)524 static Bool sna_pre_init(ScrnInfoPtr scrn, int probe)
525 {
526 struct sna *sna;
527 char buf[1024];
528 rgb defaultWeight = { 0, 0, 0 };
529 EntityInfoPtr pEnt;
530 Gamma zeros = { 0.0, 0.0, 0.0 };
531 int fd;
532
533 DBG(("%s flags=%x, numEntities=%d\n",
534 __FUNCTION__, probe, scrn->numEntities));
535
536 if (scrn->numEntities != 1)
537 return FALSE;
538
539 pEnt = xf86GetEntityInfo(scrn->entityList[0]);
540 if (pEnt == NULL) {
541 ERR(("%s: no EntityInfo found for scrn\n", __FUNCTION__));
542 return FALSE;
543 }
544
545 if (pEnt->location.type != BUS_PCI
546 #ifdef XSERVER_PLATFORM_BUS
547 && pEnt->location.type != BUS_PLATFORM
548 #endif
549 ) {
550 ERR(("%s: invalid EntityInfo found for scrn, location=%d\n", __FUNCTION__, pEnt->location.type));
551 return FALSE;
552 }
553
554 if (probe & PROBE_DETECT)
555 return TRUE;
556
557 sna_selftest();
558
559 probe = 0;
560 if (((uintptr_t)scrn->driverPrivate) & 3) {
561 if (posix_memalign((void **)&sna, 4096, sizeof(*sna)))
562 return FALSE;
563
564 memset(sna, 0, sizeof(*sna)); /* should be unnecessary */
565 probe = (uintptr_t)scrn->driverPrivate & 1;
566 sna->info = (void *)((uintptr_t)scrn->driverPrivate & ~3);
567 scrn->driverPrivate = sna;
568 sna->scrn = scrn;
569
570 sna->cpu_features = sna_cpu_detect();
571 sna->acpi.fd = sna_acpi_open();
572 }
573 sna = to_sna(scrn);
574 sna->pEnt = pEnt;
575 sna->flags = probe;
576
577 scrn->displayWidth = 640; /* default it */
578
579 scrn->monitor = scrn->confScreen->monitor;
580 scrn->progClock = TRUE;
581 scrn->rgbBits = 8;
582
583 sna->dev = intel_get_device(scrn, &fd);
584 if (sna->dev == NULL) {
585 xf86DrvMsg(scrn->scrnIndex, X_ERROR,
586 "Failed to claim DRM device.\n");
587 goto cleanup;
588 }
589
590 /* Sanity check */
591 if (hosted() && (sna->flags & SNA_IS_HOSTED) == 0) {
592 xf86DrvMsg(scrn->scrnIndex, X_ERROR,
593 "Failed to setup hosted device.\n");
594 goto cleanup;
595 }
596
597 intel_detect_chipset(scrn, sna->dev);
598 xf86DrvMsg(scrn->scrnIndex, X_PROBED,
599 "CPU: %s; using a maximum of %d threads\n",
600 sna_cpu_features_to_string(sna->cpu_features, buf),
601 sna_use_threads(64*1024, 64*1024, 1));
602
603 if (!xf86SetDepthBpp(scrn, 24, 0, 0,
604 Support32bppFb |
605 SupportConvert24to32 | PreferConvert24to32))
606 goto cleanup;
607
608 switch (scrn->depth) {
609 case 8:
610 case 15:
611 case 16:
612 case 24:
613 case 30:
614 if ((sna->flags & SNA_IS_HOSTED) ||
615 fb_supports_depth(fd, scrn->depth))
616 break;
617 /* fall through */
618 default:
619 xf86DrvMsg(scrn->scrnIndex, X_ERROR,
620 "Given depth (%d) is not supported by the Intel driver and this chipset.\n",
621 scrn->depth);
622 goto cleanup;
623 }
624 xf86PrintDepthBpp(scrn);
625
626 if (!xf86SetWeight(scrn, defaultWeight, defaultWeight))
627 goto cleanup;
628 if (!xf86SetDefaultVisual(scrn, -1))
629 goto cleanup;
630
631 sna->Options = intel_options_get(scrn);
632 if (sna->Options == NULL)
633 goto cleanup;
634
635 sna_setup_capabilities(scrn, fd);
636
637 kgem_init(&sna->kgem, fd,
638 xf86GetPciInfoForEntity(pEnt->index),
639 sna->info->gen);
640
641 if (xf86ReturnOptValBool(sna->Options, OPTION_TILING_FB, FALSE))
642 sna->flags |= SNA_LINEAR_FB;
643 if (!sna->kgem.can_fence)
644 sna->flags |= SNA_LINEAR_FB;
645
646 if (!xf86ReturnOptValBool(sna->Options, OPTION_SWAPBUFFERS_WAIT, TRUE))
647 sna->flags |= SNA_NO_WAIT;
648 DBG(("%s: swapbuffer wait? %s\n", __FUNCTION__, sna->flags & SNA_NO_WAIT ? "disabled" : "enabled"));
649
650 if (!has_vsync(sna) ||
651 !xf86ReturnOptValBool(sna->Options, OPTION_VSYNC, TRUE))
652 sna->flags |= SNA_NO_VSYNC;
653 DBG(("%s: vsync? %s\n", __FUNCTION__, sna->flags & SNA_NO_VSYNC ? "disabled" : "enabled"));
654
655 if (sna->flags & SNA_IS_HOSTED ||
656 !xf86ReturnOptValBool(sna->Options, OPTION_PAGEFLIP, TRUE))
657 sna->flags |= SNA_NO_FLIP;
658 DBG(("%s: page flips? %s\n", __FUNCTION__, sna->flags & SNA_NO_FLIP ? "disabled" : "enabled"));
659
660 if ((sna->flags & (SNA_NO_VSYNC | SNA_NO_FLIP | SNA_NO_WAIT)) == 0 &&
661 xf86ReturnOptValBool(sna->Options, OPTION_TRIPLE_BUFFER, TRUE))
662 sna->flags |= SNA_TRIPLE_BUFFER;
663 DBG(("%s: triple buffer? %s\n", __FUNCTION__, sna->flags & SNA_TRIPLE_BUFFER ? "enabled" : "disabled"));
664
665 if (xf86ReturnOptValBool(sna->Options, OPTION_CRTC_PIXMAPS, FALSE)) {
666 xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Forcing per-crtc-pixmaps.\n");
667 sna->flags |= SNA_FORCE_SHADOW;
668 }
669
670 if (!sna_mode_pre_init(scrn, sna)) {
671 xf86DrvMsg(scrn->scrnIndex, X_ERROR,
672 "No outputs and no modes.\n");
673 goto cleanup;
674 }
675 scrn->currentMode = scrn->modes;
676
677 if (!setup_tear_free(sna) && sna_mode_wants_tear_free(sna))
678 sna->kgem.needs_dirtyfb = sna->kgem.has_dirtyfb;
679
680 xf86SetGamma(scrn, zeros);
681 xf86SetDpi(scrn, 0, 0);
682
683 setup_dri(sna);
684
685 sna->present.available = false;
686 if (xf86ReturnOptValBool(sna->Options, OPTION_PRESENT, TRUE)) {
687 #if HAVE_PRESENT
688 sna->present.available = !!xf86LoadSubModule(scrn, "present");
689 #endif
690 }
691
692 sna_acpi_init(sna);
693
694 return TRUE;
695
696 cleanup:
697 scrn->driverPrivate = (void *)((uintptr_t)sna->info | (sna->flags & SNA_IS_SLAVED) | 2);
698 if (sna->dev)
699 intel_put_device(sna->dev);
700 free(sna);
701 return FALSE;
702 }
703
has_shadow(struct sna * sna)704 static bool has_shadow(struct sna *sna)
705 {
706 if (!sna->mode.shadow_enabled)
707 return false;
708
709 assert(sna->mode.shadow_damage);
710 if (RegionNil(DamageRegion(sna->mode.shadow_damage)))
711 return false;
712
713 return sna->mode.flip_active == 0;
714 }
715
716 #if !HAVE_NOTIFY_FD
717 static void
sna_block_handler(BLOCKHANDLER_ARGS_DECL)718 sna_block_handler(BLOCKHANDLER_ARGS_DECL)
719 {
720 #ifndef XF86_SCRN_INTERFACE
721 struct sna *sna = to_sna(xf86Screens[arg]);
722 #else
723 struct sna *sna = to_sna_from_screen(arg);
724 #endif
725 struct timeval **tv = timeout;
726
727 DBG(("%s (tv=%ld.%06ld), has_shadow?=%d\n", __FUNCTION__,
728 *tv ? (*tv)->tv_sec : -1, *tv ? (*tv)->tv_usec : 0,
729 has_shadow(sna)));
730
731 sna->BlockHandler(BLOCKHANDLER_ARGS);
732
733 if (*tv == NULL || ((*tv)->tv_usec | (*tv)->tv_sec) || has_shadow(sna))
734 sna_accel_block(sna, tv);
735 }
736
737 static void
sna_wakeup_handler(WAKEUPHANDLER_ARGS_DECL)738 sna_wakeup_handler(WAKEUPHANDLER_ARGS_DECL)
739 {
740 #ifndef XF86_SCRN_INTERFACE
741 struct sna *sna = to_sna(xf86Screens[arg]);
742 #else
743 struct sna *sna = to_sna_from_screen(arg);
744 #endif
745
746 DBG(("%s\n", __FUNCTION__));
747
748 /* despite all appearances, result is just a signed int */
749 if ((int)result < 0)
750 return;
751
752 sna_acpi_wakeup(sna, read_mask);
753
754 sna->WakeupHandler(WAKEUPHANDLER_ARGS);
755
756 if (FD_ISSET(sna->kgem.fd, (fd_set*)read_mask)) {
757 sna_mode_wakeup(sna);
758 /* Clear the flag so that subsequent ZaphodHeads don't block */
759 FD_CLR(sna->kgem.fd, (fd_set*)read_mask);
760 }
761 }
762 #else
763 static void
sna_block_handler(void * data,void * _timeout)764 sna_block_handler(void *data, void *_timeout)
765 {
766 struct sna *sna = data;
767 int *timeout = _timeout;
768 struct timeval tv, *tvp;
769
770 DBG(("%s (timeout=%d, has_shadow=%d)\n", __FUNCTION__,
771 *timeout, has_shadow(sna)));
772
773 if (*timeout < 0) {
774 tvp = NULL;
775 } else if (*timeout == 0) {
776 if (!has_shadow(sna))
777 return;
778
779 tv.tv_sec = 0;
780 tv.tv_usec = 0;
781 tvp = &tv;
782 } else {
783 tv.tv_sec = *timeout / 1000;
784 tv.tv_usec = (*timeout % 1000) * 1000;
785 tvp = &tv;
786 }
787
788 sna_accel_block(sna, &tvp);
789 if (tvp)
790 *timeout = tvp->tv_sec * 1000 + tvp->tv_usec / 1000;
791 }
792 #endif
793
794 #if HAVE_UDEV
795 #include <sys/stat.h>
796
797 static void
sna_handle_uevents(int fd,void * closure)798 sna_handle_uevents(int fd, void *closure)
799 {
800 struct sna *sna = closure;
801 struct stat s;
802 struct pollfd pfd;
803 bool hotplug = false;
804
805 DBG(("%s\n", __FUNCTION__));
806
807 pfd.fd = udev_monitor_get_fd(sna->uevent_monitor);
808 pfd.events = POLLIN;
809
810 if (fstat(sna->kgem.fd, &s))
811 memset(&s, 0, sizeof(s));
812
813 while (poll(&pfd, 1, 0) > 0) {
814 struct udev_device *dev;
815 dev_t devnum;
816
817 errno = 0;
818 dev = udev_monitor_receive_device(sna->uevent_monitor);
819 if (dev == NULL) {
820 if (errno == EINTR || errno == EAGAIN)
821 continue;
822
823 break;
824 }
825
826 devnum = udev_device_get_devnum(dev);
827 if (memcmp(&s.st_rdev, &devnum, sizeof(dev_t)) == 0) {
828 const char *str;
829
830 str = udev_device_get_property_value(dev, "HOTPLUG");
831 if (str && atoi(str) == 1) {
832 str = udev_device_get_property_value(dev, "CONNECTOR");
833 if (str) {
834 hotplug |= sna_mode_find_hotplug_connector(sna, atoi(str));
835 } else {
836 sna->flags |= SNA_REPROBE;
837 hotplug = true;
838 }
839 }
840 }
841
842 udev_device_unref(dev);
843 }
844
845 if (hotplug) {
846 DBG(("%s: hotplug event (vtSema?=%d)\n",
847 __FUNCTION__, sna->scrn->vtSema));
848
849 if (sna->scrn->vtSema)
850 sna_mode_discover(sna, true);
851 else
852 sna->flags |= SNA_REPROBE;
853 }
854 }
855
has_randr(void)856 static bool has_randr(void)
857 {
858 #if HAS_DIXREGISTERPRIVATEKEY
859 return dixPrivateKeyRegistered(rrPrivKey);
860 #else
861 return *rrPrivKey;
862 #endif
863 }
864
865 static void
sna_uevent_init(struct sna * sna)866 sna_uevent_init(struct sna *sna)
867 {
868 struct udev *u;
869 struct udev_monitor *mon;
870 MessageType from = X_CONFIG;
871
872 if (sna->flags & SNA_IS_HOSTED)
873 return;
874
875 DBG(("%s\n", __FUNCTION__));
876
877 /* RandR will be disabled if Xinerama is active, and so generating
878 * RR hotplug events is then verboten.
879 */
880 if (!has_randr())
881 goto out;
882
883 u = NULL;
884 if (xf86ReturnOptValBool(sna->Options, OPTION_HOTPLUG, TRUE))
885 u = udev_new();
886 if (!u)
887 goto out;
888
889 from = X_DEFAULT;
890
891 mon = udev_monitor_new_from_netlink(u, "udev");
892 if (!mon)
893 goto err_dev;
894
895 if (udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", "drm_minor") < 0)
896 goto err_monitor;
897
898 if (udev_monitor_enable_receiving(mon) < 0)
899 goto err_monitor;
900
901 sna->uevent_handler = xf86AddGeneralHandler(udev_monitor_get_fd(mon),
902 sna_handle_uevents, sna);
903 if (!sna->uevent_handler)
904 goto err_monitor;
905
906 sna->uevent_monitor = mon;
907 out:
908 xf86DrvMsg(sna->scrn->scrnIndex, from,
909 "Display hotplug detection %s\n",
910 sna->uevent_monitor ? "enabled" : "disabled");
911 return;
912
913 err_monitor:
914 udev_monitor_unref(mon);
915 err_dev:
916 udev_unref(u);
917 goto out;
918 }
919
sna_uevent_poll(struct sna * sna)920 static bool sna_uevent_poll(struct sna *sna)
921 {
922 if (sna->uevent_monitor == NULL)
923 return false;
924
925 sna_handle_uevents(udev_monitor_get_fd(sna->uevent_monitor), sna);
926 return true;
927 }
928
929 static void
sna_uevent_fini(struct sna * sna)930 sna_uevent_fini(struct sna *sna)
931 {
932 struct udev *u;
933
934 if (sna->uevent_handler == NULL)
935 return;
936
937 xf86RemoveGeneralHandler(sna->uevent_handler);
938
939 u = udev_monitor_get_udev(sna->uevent_monitor);
940 udev_monitor_unref(sna->uevent_monitor);
941 udev_unref(u);
942
943 sna->uevent_handler = NULL;
944 sna->uevent_monitor = NULL;
945
946 DBG(("%s: removed uvent handler\n", __FUNCTION__));
947 }
948 #else
sna_uevent_init(struct sna * sna)949 static void sna_uevent_init(struct sna *sna) { }
sna_uevent_poll(struct sna * sna)950 static bool sna_uevent_poll(struct sna *sna) { return false; }
sna_uevent_fini(struct sna * sna)951 static void sna_uevent_fini(struct sna *sna) { }
952 #endif /* HAVE_UDEV */
953
954 static Bool
sna_randr_getinfo(ScreenPtr screen,Rotation * rotations)955 sna_randr_getinfo(ScreenPtr screen, Rotation *rotations)
956 {
957 struct sna *sna = to_sna_from_screen(screen);
958
959 DBG(("%s()\n", __FUNCTION__));
960
961 if (!sna_uevent_poll(sna))
962 sna_mode_discover(sna, false);
963
964 return sna->mode.rrGetInfo(screen, rotations);
965 }
966
sna_leave_vt(VT_FUNC_ARGS_DECL)967 static void sna_leave_vt(VT_FUNC_ARGS_DECL)
968 {
969 SCRN_INFO_PTR(arg);
970 struct sna *sna = to_sna(scrn);
971
972 DBG(("%s(vtSema=%d)\n", __FUNCTION__, scrn->vtSema));
973
974 sna_mode_reset(sna);
975 sna_accel_leave(sna);
976
977 if (scrn->vtSema && intel_put_master(sna->dev))
978 xf86DrvMsg(scrn->scrnIndex, X_WARNING,
979 "drmDropMaster failed: %s\n", strerror(errno));
980
981 scrn->vtSema = FALSE;
982 }
983
sna_early_close_screen(CLOSE_SCREEN_ARGS_DECL)984 static Bool sna_early_close_screen(CLOSE_SCREEN_ARGS_DECL)
985 {
986 ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
987 struct sna *sna = to_sna(scrn);
988
989 DBG(("%s\n", __FUNCTION__));
990
991 /* XXX Note that we will leak kernel resources if !vtSema */
992
993 #if HAVE_NOTIFY_FD
994 RemoveBlockAndWakeupHandlers(sna_block_handler,
995 (ServerWakeupHandlerProcPtr)NoopDDA,
996 sna);
997 #endif
998
999 sna_uevent_fini(sna);
1000 sna_mode_close(sna);
1001
1002 if (sna->present.open) {
1003 sna_present_close(sna, screen);
1004 sna->present.open = false;
1005 }
1006
1007 if (sna->dri3.open) {
1008 sna_dri3_close(sna, screen);
1009 sna->dri3.open = false;
1010 }
1011
1012 if (sna->dri2.open) {
1013 sna_dri2_close(sna, screen);
1014 sna->dri2.open = false;
1015 }
1016
1017 if (sna->front) {
1018 screen->DestroyPixmap(sna->front);
1019 sna->front = NULL;
1020 }
1021
1022 if (scrn->vtSema) {
1023 intel_put_master(sna->dev);
1024 scrn->vtSema = FALSE;
1025 }
1026
1027 return sna->CloseScreen(CLOSE_SCREEN_ARGS);
1028 }
1029
sna_late_close_screen(CLOSE_SCREEN_ARGS_DECL)1030 static Bool sna_late_close_screen(CLOSE_SCREEN_ARGS_DECL)
1031 {
1032 struct sna *sna = to_sna_from_screen(screen);
1033 DepthPtr depths;
1034 int d;
1035
1036 DBG(("%s\n", __FUNCTION__));
1037
1038 sna_accel_close(sna);
1039 sna_video_close(sna);
1040
1041 depths = screen->allowedDepths;
1042 for (d = 0; d < screen->numDepths; d++)
1043 free(depths[d].vids);
1044 free(depths);
1045
1046 free(screen->visuals);
1047
1048 return TRUE;
1049 }
1050
1051 static Bool
sna_register_all_privates(void)1052 sna_register_all_privates(void)
1053 {
1054 #if HAS_DIXREGISTERPRIVATEKEY
1055 if (!dixRegisterPrivateKey(&sna_pixmap_key, PRIVATE_PIXMAP,
1056 3*sizeof(void *)))
1057 return FALSE;
1058
1059 if (!dixRegisterPrivateKey(&sna_gc_key, PRIVATE_GC,
1060 sizeof(FbGCPrivate)))
1061 return FALSE;
1062
1063 if (!dixRegisterPrivateKey(&sna_glyph_key, PRIVATE_GLYPH,
1064 sizeof(struct sna_glyph)))
1065 return FALSE;
1066
1067 if (!dixRegisterPrivateKey(&sna_window_key, PRIVATE_WINDOW,
1068 3*sizeof(void *)))
1069 return FALSE;
1070
1071 if (!dixRegisterPrivateKey(&sna_client_key, PRIVATE_CLIENT,
1072 sizeof(struct sna_client)))
1073 return FALSE;
1074 #else
1075 if (!dixRequestPrivate(&sna_pixmap_key, 3*sizeof(void *)))
1076 return FALSE;
1077
1078 if (!dixRequestPrivate(&sna_gc_key, sizeof(FbGCPrivate)))
1079 return FALSE;
1080
1081 if (!dixRequestPrivate(&sna_glyph_key, sizeof(struct sna_glyph)))
1082 return FALSE;
1083
1084 if (!dixRequestPrivate(&sna_window_key, 3*sizeof(void *)))
1085 return FALSE;
1086
1087 if (!dixRequestPrivate(&sna_client_key, sizeof(struct sna_client)))
1088 return FALSE;
1089 #endif
1090
1091 return TRUE;
1092 }
1093
sna_dri_init(struct sna * sna,ScreenPtr screen)1094 static void sna_dri_init(struct sna *sna, ScreenPtr screen)
1095 {
1096 char str[128] = "";
1097
1098 if (sna->dri2.enable)
1099 sna->dri2.open = sna_dri2_open(sna, screen);
1100 if (sna->dri2.open)
1101 strcat(str, "DRI2 ");
1102
1103 /* Load DRI3 in case DRI2 doesn't work, e.g. vgaarb */
1104 if (sna->dri3.enable || (!sna->dri2.open && !sna->dri3.override))
1105 sna->dri3.open = sna_dri3_open(sna, screen);
1106 if (sna->dri3.open)
1107 strcat(str, "DRI3 ");
1108
1109 if (*str)
1110 xf86DrvMsg(sna->scrn->scrnIndex, X_INFO,
1111 "direct rendering: %senabled\n", str);
1112 }
1113
1114 static Bool
sna_mode_init(struct sna * sna,ScreenPtr screen)1115 sna_mode_init(struct sna *sna, ScreenPtr screen)
1116 {
1117 rrScrPrivPtr rp;
1118
1119 if (!xf86CrtcScreenInit(screen))
1120 return FALSE;
1121
1122 xf86RandR12SetRotations(screen, RR_Rotate_All | RR_Reflect_All);
1123 xf86RandR12SetTransformSupport(screen, TRUE);
1124
1125 /* Wrap RR queries to catch pending MST topology changes */
1126 rp = rrGetScrPriv(screen);
1127 if (rp) {
1128 sna->mode.rrGetInfo = rp->rrGetInfo;
1129 rp->rrGetInfo = sna_randr_getinfo;
1130
1131 /* Simulate a hotplug event on wakeup to force a RR probe */
1132 TimerSet(NULL, 0, COLDPLUG_DELAY_MS, sna_mode_coldplug, sna);
1133 }
1134
1135 return TRUE;
1136 }
1137
1138 static Bool
sna_screen_init(SCREEN_INIT_ARGS_DECL)1139 sna_screen_init(SCREEN_INIT_ARGS_DECL)
1140 {
1141 ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
1142 struct sna *sna = to_sna(scrn);
1143 VisualPtr visuals;
1144 DepthPtr depths;
1145 int nvisuals;
1146 int ndepths;
1147 int rootdepth;
1148 VisualID defaultVisual;
1149
1150 DBG(("%s\n", __FUNCTION__));
1151
1152 assert(sna->scrn == scrn);
1153 assert(to_screen_from_sna(sna) == NULL || /* set afterwards */
1154 to_screen_from_sna(sna) == screen);
1155
1156 assert(sna->freed_pixmap == NULL);
1157
1158 if (!sna_register_all_privates())
1159 return FALSE;
1160
1161 scrn->videoRam = sna->kgem.aperture_mappable * 4; /* Page to KiB */
1162
1163 miClearVisualTypes();
1164 if (!miSetVisualTypes(scrn->depth,
1165 miGetDefaultVisualMask(scrn->depth),
1166 scrn->rgbBits, scrn->defaultVisual))
1167 return FALSE;
1168 if (!miSetPixmapDepths())
1169 return FALSE;
1170
1171 rootdepth = 0;
1172 if (!miInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
1173 &defaultVisual,
1174 ((unsigned long)1 << (scrn->bitsPerPixel - 1)),
1175 scrn->rgbBits, -1))
1176 return FALSE;
1177
1178 if (!miScreenInit(screen, NULL,
1179 scrn->virtualX, scrn->virtualY,
1180 scrn->xDpi, scrn->yDpi, 0,
1181 rootdepth, ndepths, depths,
1182 defaultVisual, nvisuals, visuals))
1183 return FALSE;
1184
1185 if (scrn->bitsPerPixel > 8) {
1186 /* Fixup RGB ordering */
1187 VisualPtr visual = screen->visuals + screen->numVisuals;
1188 while (--visual >= screen->visuals) {
1189 if ((visual->class | DynamicClass) == DirectColor) {
1190 visual->offsetRed = scrn->offset.red;
1191 visual->offsetGreen = scrn->offset.green;
1192 visual->offsetBlue = scrn->offset.blue;
1193 visual->redMask = scrn->mask.red;
1194 visual->greenMask = scrn->mask.green;
1195 visual->blueMask = scrn->mask.blue;
1196 }
1197 }
1198 }
1199
1200 assert(screen->CloseScreen == NULL);
1201 screen->CloseScreen = sna_late_close_screen;
1202 if (!sna_accel_init(screen, sna)) {
1203 xf86DrvMsg(scrn->scrnIndex, X_ERROR,
1204 "Hardware acceleration initialization failed\n");
1205 return FALSE;
1206 }
1207
1208 xf86SetBlackWhitePixels(screen);
1209
1210 xf86SetBackingStore(screen);
1211 xf86SetSilkenMouse(screen);
1212 if (!miDCInitialize(screen, xf86GetPointerScreenFuncs()))
1213 return FALSE;
1214
1215 if (sna_cursors_init(screen, sna))
1216 xf86DrvMsg(scrn->scrnIndex, X_INFO, "HW Cursor enabled\n");
1217
1218 /* Must force it before EnterVT, so we are in control of VT and
1219 * later memory should be bound when allocating, e.g rotate_mem */
1220 scrn->vtSema = TRUE;
1221
1222 #if !HAVE_NOTIFY_FD
1223 sna->BlockHandler = screen->BlockHandler;
1224 screen->BlockHandler = sna_block_handler;
1225
1226 sna->WakeupHandler = screen->WakeupHandler;
1227 screen->WakeupHandler = sna_wakeup_handler;
1228 #else
1229 RegisterBlockAndWakeupHandlers(sna_block_handler,
1230 (ServerWakeupHandlerProcPtr)NoopDDA,
1231 sna);
1232 #endif
1233
1234 screen->SaveScreen = sna_save_screen;
1235 screen->CreateScreenResources = sna_create_screen_resources;
1236
1237 sna->CloseScreen = screen->CloseScreen;
1238 screen->CloseScreen = sna_early_close_screen;
1239
1240 if (!sna_mode_init(sna, screen))
1241 return FALSE;
1242
1243 if (!miCreateDefColormap(screen))
1244 return FALSE;
1245
1246 /* X-Server < 1.20 mishandles > 256 slots / > 8 bpc color maps. */
1247 if (sna->mode.num_real_crtc && (scrn->rgbBits <= 8 ||
1248 XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,20,0,0,0)) &&
1249 !xf86HandleColormaps(screen, 1 << scrn->rgbBits, scrn->rgbBits,
1250 sna_load_palette, NULL,
1251 CMAP_RELOAD_ON_MODE_SWITCH |
1252 CMAP_PALETTED_TRUECOLOR))
1253 return FALSE;
1254
1255 if (!xf86CheckBoolOption(scrn->options, "dpms", TRUE))
1256 sna->flags |= SNA_NO_DPMS;
1257 xf86DPMSInit(screen, sna_dpms_set, 0);
1258
1259 sna_uevent_init(sna);
1260 sna_video_init(sna, screen);
1261 sna_dri_init(sna, screen);
1262
1263 if (sna->present.available)
1264 sna->present.open = sna_present_open(sna, screen);
1265 if (sna->present.open)
1266 xf86DrvMsg(sna->scrn->scrnIndex, X_INFO,
1267 "hardware support for Present enabled\n");
1268
1269 if (serverGeneration == 1)
1270 xf86ShowUnusedOptions(scrn->scrnIndex, scrn->options);
1271
1272 sna->suspended = FALSE;
1273
1274 return TRUE;
1275 }
1276
sna_adjust_frame(ADJUST_FRAME_ARGS_DECL)1277 static void sna_adjust_frame(ADJUST_FRAME_ARGS_DECL)
1278 {
1279 SCRN_INFO_PTR(arg);
1280 DBG(("%s(%d, %d)\n", __FUNCTION__, x, y));
1281 sna_mode_adjust_frame(to_sna(scrn), x, y);
1282 }
1283
sna_free_screen(FREE_SCREEN_ARGS_DECL)1284 static void sna_free_screen(FREE_SCREEN_ARGS_DECL)
1285 {
1286 SCRN_INFO_PTR(arg);
1287 struct sna *sna = to_sna(scrn);
1288
1289 DBG(("%s [scrn=%p, sna=%p]\n", __FUNCTION__, scrn, sna));
1290 if (sna == NULL || (uintptr_t)sna & 3) /* beware thieves */
1291 return;
1292
1293 scrn->driverPrivate = (void *)((uintptr_t)sna->info | (sna->flags & SNA_IS_SLAVED) | 2);
1294
1295 sna_mode_fini(sna);
1296 sna_acpi_fini(sna);
1297
1298 intel_put_device(sna->dev);
1299 free(sna);
1300 }
1301
sna_enter_vt(VT_FUNC_ARGS_DECL)1302 static Bool sna_enter_vt(VT_FUNC_ARGS_DECL)
1303 {
1304 SCRN_INFO_PTR(arg);
1305 struct sna *sna = to_sna(scrn);
1306
1307 DBG(("%s(vtSema=%d)\n", __FUNCTION__, scrn->vtSema));
1308 if (intel_get_master(sna->dev))
1309 return FALSE;
1310
1311 scrn->vtSema = TRUE;
1312 sna_accel_enter(sna);
1313
1314 if (sna->flags & SNA_REPROBE) {
1315 DBG(("%s: reporting deferred hotplug event\n", __FUNCTION__));
1316 sna_mode_discover(sna, true);
1317 }
1318
1319 sna_set_desired_mode(sna);
1320
1321 return TRUE;
1322 }
1323
sna_switch_mode(SWITCH_MODE_ARGS_DECL)1324 static Bool sna_switch_mode(SWITCH_MODE_ARGS_DECL)
1325 {
1326 SCRN_INFO_PTR(arg);
1327 DBG(("%s\n", __FUNCTION__));
1328 return xf86SetSingleMode(scrn, mode, RR_Rotate_0);
1329 }
1330
1331 static ModeStatus
sna_valid_mode(SCRN_ARG_TYPE arg,DisplayModePtr mode,Bool verbose,int flags)1332 sna_valid_mode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
1333 {
1334 return MODE_OK;
1335 }
1336
1337 #ifndef SUSPEND_SLEEP
1338 #define SUSPEND_SLEEP 0
1339 #endif
1340 #ifndef RESUME_SLEEP
1341 #define RESUME_SLEEP 0
1342 #endif
1343
1344 /*
1345 * This function is only required if we need to do anything differently from
1346 * DoApmEvent() in common/xf86PM.c, including if we want to see events other
1347 * than suspend/resume.
1348 */
sna_pm_event(SCRN_ARG_TYPE arg,pmEvent event,Bool undo)1349 static Bool sna_pm_event(SCRN_ARG_TYPE arg, pmEvent event, Bool undo)
1350 {
1351 SCRN_INFO_PTR(arg);
1352 struct sna *sna = to_sna(scrn);
1353
1354 DBG(("%s\n", __FUNCTION__));
1355
1356 switch (event) {
1357 case XF86_APM_SYS_SUSPEND:
1358 case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend? */
1359 case XF86_APM_USER_SUSPEND:
1360 case XF86_APM_SYS_STANDBY:
1361 case XF86_APM_USER_STANDBY:
1362 if (!undo && !sna->suspended) {
1363 scrn->LeaveVT(VT_FUNC_ARGS(0));
1364 sna->suspended = TRUE;
1365 sleep(SUSPEND_SLEEP);
1366 } else if (undo && sna->suspended) {
1367 sleep(RESUME_SLEEP);
1368 scrn->EnterVT(VT_FUNC_ARGS(0));
1369 sna->suspended = FALSE;
1370 }
1371 break;
1372 case XF86_APM_STANDBY_RESUME:
1373 case XF86_APM_NORMAL_RESUME:
1374 case XF86_APM_CRITICAL_RESUME:
1375 if (sna->suspended) {
1376 sleep(RESUME_SLEEP);
1377 scrn->EnterVT(VT_FUNC_ARGS(0));
1378 sna->suspended = FALSE;
1379 /*
1380 * Turn the screen saver off when resuming. This seems to be
1381 * needed to stop xscreensaver kicking in (when used).
1382 *
1383 * XXX DoApmEvent() should probably call this just like
1384 * xf86VTSwitch() does. Maybe do it here only in 4.2
1385 * compatibility mode.
1386 */
1387 SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
1388 }
1389 break;
1390 /* This is currently used for ACPI */
1391 case XF86_APM_CAPABILITY_CHANGED:
1392 SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
1393 break;
1394
1395 default:
1396 ERR(("sna_pm_event: received APM event %d\n", event));
1397 }
1398 return TRUE;
1399 }
1400
sna_enter_vt__hosted(VT_FUNC_ARGS_DECL)1401 static Bool sna_enter_vt__hosted(VT_FUNC_ARGS_DECL)
1402 {
1403 return TRUE;
1404 }
1405
sna_leave_vt__hosted(VT_FUNC_ARGS_DECL)1406 static void sna_leave_vt__hosted(VT_FUNC_ARGS_DECL)
1407 {
1408 }
1409
describe_kms(ScrnInfoPtr scrn)1410 static void describe_kms(ScrnInfoPtr scrn)
1411 {
1412 int fd = __intel_peek_fd(scrn);
1413 drm_version_t version;
1414 char name[128] = "";
1415 char date[128] = "";
1416
1417 memset(&version, 0, sizeof(version));
1418 version.name_len = sizeof(name) - 1;
1419 version.name = name;
1420 version.date_len = sizeof(date) - 1;
1421 version.date = date;
1422
1423 if (drmIoctl(fd, DRM_IOCTL_VERSION, &version))
1424 return;
1425
1426 xf86DrvMsg(scrn->scrnIndex, X_INFO,
1427 "Using Kernel Mode Setting driver: %s, version %d.%d.%d %s\n",
1428 version.name,
1429 version.version_major, version.version_minor, version.version_patchlevel,
1430 version.date);
1431 }
1432
describe_sna(ScrnInfoPtr scrn)1433 static void describe_sna(ScrnInfoPtr scrn)
1434 {
1435 #if defined(USE_GIT_DESCRIBE)
1436 xf86DrvMsg(scrn->scrnIndex, X_INFO,
1437 "SNA compiled from %s\n", git_version);
1438 #elif defined(BUILDER_DESCRIPTION)
1439 xf86DrvMsg(scrn->scrnIndex, X_INFO,
1440 "SNA compiled: %s\n", BUILDER_DESCRIPTION);
1441 #endif
1442 #if HAS_DEBUG_FULL
1443 ErrorF("SNA compiled with full debug logging; expect to run slowly\n");
1444 #endif
1445 #if !NDEBUG
1446 xf86DrvMsg(scrn->scrnIndex, X_INFO,
1447 "SNA compiled with assertions enabled\n");
1448 #endif
1449 #if DEBUG_SYNC
1450 xf86DrvMsg(scrn->scrnIndex, X_INFO,
1451 "SNA compiled with synchronous rendering\n");
1452 #endif
1453 #if DEBUG_MEMORY
1454 xf86DrvMsg(scrn->scrnIndex, X_INFO,
1455 "SNA compiled with memory allocation reporting enabled\n");
1456 #endif
1457 #if DEBUG_PIXMAP
1458 xf86DrvMsg(scrn->scrnIndex, X_INFO,
1459 "SNA compiled with extra pixmap/damage validation\n");
1460 #endif
1461 #ifdef HAVE_VALGRIND
1462 xf86DrvMsg(scrn->scrnIndex, X_INFO,
1463 "SNA compiled for use with valgrind\n");
1464 VALGRIND_PRINTF("SNA compiled for use with valgrind\n");
1465 #endif
1466 DBG(("xf86-video-intel version: %s\n", git_version));
1467 DBG(("pixman version: %s\n", pixman_version_string()));
1468 }
1469
sna_init_scrn(ScrnInfoPtr scrn,int entity_num)1470 Bool sna_init_scrn(ScrnInfoPtr scrn, int entity_num)
1471 {
1472 DBG(("%s: entity_num=%d\n", __FUNCTION__, entity_num));
1473 describe_kms(scrn);
1474 describe_sna(scrn);
1475
1476 scrn->PreInit = sna_pre_init;
1477 scrn->ScreenInit = sna_screen_init;
1478 if (!hosted()) {
1479 scrn->SwitchMode = sna_switch_mode;
1480 scrn->AdjustFrame = sna_adjust_frame;
1481 scrn->EnterVT = sna_enter_vt;
1482 scrn->LeaveVT = sna_leave_vt;
1483 scrn->ValidMode = sna_valid_mode;
1484 scrn->PMEvent = sna_pm_event;
1485 } else {
1486 scrn->EnterVT = sna_enter_vt__hosted;
1487 scrn->LeaveVT = sna_leave_vt__hosted;
1488 }
1489 scrn->FreeScreen = sna_free_screen;
1490
1491 xf86SetEntitySharable(entity_num);
1492 xf86SetEntityInstanceForScreen(scrn, entity_num,
1493 xf86GetNumEntityInstances(entity_num)-1);
1494
1495 sna_threads_init();
1496
1497 return TRUE;
1498 }
1499
1500 #if HAS_DEBUG_FULL
LogF(const char * f,...)1501 _X_ATTRIBUTE_PRINTF(1, 0) void LogF(const char *f, ...)
1502 {
1503 va_list ap;
1504
1505 /* As we not only may be called from any context, we may also
1506 * be called from a thread whilst the main thread is handling
1507 * signals, therefore we have to use the signal-safe variants
1508 * or else we trip over false positive assertions.
1509 */
1510
1511 va_start(ap, f);
1512 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0)
1513 LogVMessageVerbSigSafe(X_NONE, 1, f, ap);
1514 #else
1515 LogVMessageVerb(X_NONE, 1, f, ap);
1516 #endif
1517 va_end(ap);
1518 }
1519 #endif
1520