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