1 /*
2  * Copyright © 2007 Red Hat, Inc.
3  * Copyright © 2013-2014 Intel Corporation
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * Authors:
25  *    Dave Airlie <airlied@redhat.com>
26  *
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include <stdint.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <sys/mman.h>
37 #include <fcntl.h>
38 #include <unistd.h>
39 #include <errno.h>
40 #include <poll.h>
41 #include <ctype.h>
42 #include <dirent.h>
43 
44 #if HAVE_ALLOCA_H
45 #include <alloca.h>
46 #elif defined __GNUC__
47 #define alloca __builtin_alloca
48 #elif defined _AIX
49 #define alloca __alloca
50 #elif defined _MSC_VER
51 #include <malloc.h>
52 #define alloca _alloca
53 #else
54 void *alloca(size_t);
55 #endif
56 
57 #define _PARSE_EDID_
58 /* Jump through a few hoops in order to fixup EDIDs */
59 #undef VERSION
60 #undef REVISION
61 
62 #include "sna.h"
63 #include "sna_reg.h"
64 #include "fb/fbpict.h"
65 #include "intel_options.h"
66 #include "backlight.h"
67 
68 #include <xf86Crtc.h>
69 #include <xf86RandR12.h>
70 #include <cursorstr.h>
71 
72 #if XF86_CRTC_VERSION >= 3
73 #define HAS_GAMMA 1
74 #else
75 #define HAS_GAMMA 0
76 #endif
77 
78 #include <X11/Xatom.h>
79 #if defined(HAVE_X11_EXTENSIONS_DPMSCONST_H)
80 #include <X11/extensions/dpmsconst.h>
81 #else
82 #define DPMSModeOn 0
83 #define DPMSModeOff 3
84 #endif
85 #include <xf86DDC.h> /* for xf86InterpretEDID */
86 
87 #include <xf86drm.h>
88 
89 #ifdef HAVE_VALGRIND
90 #include <valgrind.h>
91 #include <memcheck.h>
92 #endif
93 
94 #define FAIL_CURSOR_IOCTL 0
95 
96 /* Minor discrepancy between 32-bit/64-bit ABI in old kernels */
97 union compat_mode_get_connector{
98 	struct drm_mode_get_connector conn;
99 	uint32_t pad[20];
100 };
101 
102 #define KNOWN_MODE_FLAGS ((1<<14)-1)
103 
104 #ifndef MONITOR_EDID_COMPLETE_RAWDATA
105 #define MONITOR_EDID_COMPLETE_RAWDATA 1
106 #endif
107 
108 #ifndef DEFAULT_DPI
109 #define DEFAULT_DPI 96
110 #endif
111 
112 #define OUTPUT_STATUS_CACHE_MS 15000
113 
114 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
115 
116 #define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
117 #define DRM_PLANE_TYPE_OVERLAY 0
118 #define DRM_PLANE_TYPE_PRIMARY 1
119 #define DRM_PLANE_TYPE_CURSOR  2
120 
121 #define LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xb9, struct local_mode_obj_get_properties)
122 struct local_mode_obj_get_properties {
123 	uint64_t props_ptr;
124 	uint64_t prop_values_ptr;
125 	uint32_t count_props;
126 	uint32_t obj_id;
127 	uint32_t obj_type;
128 	uint32_t pad;
129 };
130 #define LOCAL_MODE_OBJECT_CRTC 0xcccccccc
131 #define LOCAL_MODE_OBJECT_PLANE 0xeeeeeeee
132 
133 struct local_mode_set_plane {
134 	uint32_t plane_id;
135 	uint32_t crtc_id;
136 	uint32_t fb_id; /* fb object contains surface format type */
137 	uint32_t flags;
138 
139 	/* Signed dest location allows it to be partially off screen */
140 	int32_t crtc_x, crtc_y;
141 	uint32_t crtc_w, crtc_h;
142 
143 	/* Source values are 16.16 fixed point */
144 	uint32_t src_x, src_y;
145 	uint32_t src_h, src_w;
146 };
147 #define LOCAL_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct local_mode_set_plane)
148 
149 struct local_mode_get_plane {
150 	uint32_t plane_id;
151 
152 	uint32_t crtc_id;
153 	uint32_t fb_id;
154 
155 	uint32_t possible_crtcs;
156 	uint32_t gamma_size;
157 
158 	uint32_t count_format_types;
159 	uint64_t format_type_ptr;
160 };
161 #define LOCAL_IOCTL_MODE_GETPLANE DRM_IOWR(0xb6, struct local_mode_get_plane)
162 
163 struct local_mode_get_plane_res {
164 	uint64_t plane_id_ptr;
165 	uint64_t count_planes;
166 };
167 #define LOCAL_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xb5, struct local_mode_get_plane_res)
168 
169 #if 1
170 #define __DBG DBG
171 #else
172 #define __DBG(x)
173 #endif
174 
175 #define DBG_NATIVE_ROTATION ~0 /* minimum RR_Rotate_0 */
176 
177 extern XF86ConfigPtr xf86configptr;
178 
179 struct sna_cursor {
180 	struct sna_cursor *next;
181 	uint32_t *image;
182 	bool transformed;
183 	Rotation rotation;
184 	int ref;
185 	int size;
186 	int last_width;
187 	int last_height;
188 	unsigned handle;
189 	unsigned serial;
190 	unsigned alloc;
191 };
192 
193 struct sna_crtc {
194 	struct sna_crtc_public public;
195 	uint32_t id;
196 	xf86CrtcPtr base;
197 	struct drm_mode_modeinfo kmode;
198 	PixmapPtr slave_pixmap;
199 	DamagePtr slave_damage;
200 	struct kgem_bo *bo, *shadow_bo, *client_bo, *cache_bo;
201 	struct sna_cursor *cursor;
202 	unsigned int last_cursor_size;
203 	uint32_t offset;
204 	bool shadow;
205 	bool fallback_shadow;
206 	bool transform;
207 	bool cursor_transform;
208 	bool hwcursor;
209 	bool flip_pending;
210 
211 	struct pict_f_transform cursor_to_fb, fb_to_cursor;
212 
213 	RegionRec crtc_damage;
214 	uint16_t shadow_bo_width, shadow_bo_height;
215 
216 	uint32_t rotation;
217 	struct plane {
218 		uint32_t id;
219 		uint32_t type;
220 		struct {
221 			uint32_t prop;
222 			uint32_t supported;
223 			uint32_t current;
224 		} rotation;
225 		struct {
226 			uint32_t prop;
227 			uint64_t values[2];
228 		} color_encoding;
229 		struct list link;
230 	} primary;
231 	struct list sprites;
232 
233 	struct drm_color_lut *gamma_lut;
234 	uint64_t gamma_lut_prop;
235 	uint64_t gamma_lut_blob;
236 	uint32_t gamma_lut_size;
237 
238 	uint32_t mode_serial, flip_serial;
239 
240 	uint32_t last_seq, wrap_seq;
241 	struct ust_msc swap;
242 
243 	sna_flip_handler_t flip_handler;
244 	struct kgem_bo *flip_bo;
245 	void *flip_data;
246 
247 	struct list shadow_link;
248 };
249 
250 struct sna_property {
251 	drmModePropertyPtr kprop;
252 	int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */
253 	Atom *atoms;
254 };
255 
256 struct sna_output {
257 	xf86OutputPtr base;
258 	unsigned id;
259 	unsigned serial;
260 
261 	unsigned possible_encoders;
262 	unsigned attached_encoders;
263 
264 	unsigned int is_panel : 1;
265 	unsigned int add_default_modes : 1;
266 	int connector_type;
267 	int connector_type_id;
268 
269 	uint32_t link_status_idx;
270 
271 	uint32_t edid_idx;
272 	uint32_t edid_blob_id;
273 	uint32_t edid_len;
274 	void *edid_raw;
275 	void *fake_edid_raw;
276 
277 	bool has_panel_limits;
278 	int panel_hdisplay;
279 	int panel_vdisplay;
280 
281 	uint32_t dpms_id;
282 	uint8_t dpms_mode;
283 	struct backlight backlight;
284 	int backlight_active_level;
285 
286 	uint32_t last_detect;
287 	uint32_t status;
288 	unsigned int hotplug_count;
289 	bool update_properties;
290 	bool reprobe;
291 
292 	int num_modes;
293 	struct drm_mode_modeinfo *modes;
294 
295 	int num_props;
296 	uint32_t *prop_ids;
297 	uint64_t *prop_values;
298 	struct sna_property *props;
299 };
300 
301 enum { /* XXX copied from hw/xfree86/modes/xf86Crtc.c */
302 	OPTION_PREFERRED_MODE,
303 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,1,0)
304 	OPTION_ZOOM_MODES,
305 #endif
306 	OPTION_POSITION,
307 	OPTION_BELOW,
308 	OPTION_RIGHT_OF,
309 	OPTION_ABOVE,
310 	OPTION_LEFT_OF,
311 	OPTION_ENABLE,
312 	OPTION_DISABLE,
313 	OPTION_MIN_CLOCK,
314 	OPTION_MAX_CLOCK,
315 	OPTION_IGNORE,
316 	OPTION_ROTATE,
317 	OPTION_PANNING,
318 	OPTION_PRIMARY,
319 	OPTION_DEFAULT_MODES,
320 };
321 
322 static void __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup);
323 static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc);
324 static bool sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc,
325 			  struct kgem_bo *bo, int x, int y);
326 static void sna_crtc_gamma_set(xf86CrtcPtr crtc,
327 			       CARD16 *red, CARD16 *green,
328 			       CARD16 *blue, int size);
329 
is_zaphod(ScrnInfoPtr scrn)330 static bool is_zaphod(ScrnInfoPtr scrn)
331 {
332 	return xf86IsEntityShared(scrn->entityList[0]);
333 }
334 
335 static bool
sna_zaphod_match(struct sna * sna,const char * output)336 sna_zaphod_match(struct sna *sna, const char *output)
337 {
338 	const char *s, *colon;
339 	char t[20];
340 	unsigned int i = 0;
341 
342 	s = xf86GetOptValString(sna->Options, OPTION_ZAPHOD);
343 	if (s == NULL)
344 		return false;
345 
346 	colon = strchr(s, ':');
347 	if (colon) /* Skip over the ZaphodPipes */
348 		s = colon + 1;
349 
350 	do {
351 		/* match any outputs in a comma list, stopping at whitespace */
352 		switch (*s) {
353 		case '\0':
354 			t[i] = '\0';
355 			return strcmp(t, output) == 0;
356 
357 		case ',':
358 			t[i] ='\0';
359 			if (strcmp(t, output) == 0)
360 				return TRUE;
361 			i = 0;
362 			break;
363 
364 		case ' ':
365 		case '\t':
366 		case '\n':
367 		case '\r':
368 			break;
369 
370 		default:
371 			t[i++] = *s;
372 			break;
373 		}
374 
375 		s++;
376 	} while (i < sizeof(t));
377 
378 	return false;
379 }
380 
381 static unsigned
get_zaphod_crtcs(struct sna * sna)382 get_zaphod_crtcs(struct sna *sna)
383 {
384 	const char *str, *colon;
385 	unsigned crtcs = 0;
386 
387 	str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD);
388 	if (str == NULL || (colon = strchr(str, ':')) == NULL) {
389 		DBG(("%s: no zaphod pipes, using screen number: %x\n",
390 		     __FUNCTION__,
391 		     sna->scrn->confScreen->device->screen));
392 		return 1 << sna->scrn->confScreen->device->screen;
393 	}
394 
395 	DBG(("%s: ZaphodHeads='%s'\n", __FUNCTION__, str));
396 	while (str < colon) {
397 		char *end;
398 		unsigned crtc = strtoul(str, &end, 0);
399 		if (end == str)
400 			break;
401 		DBG(("%s: adding CRTC %d to zaphod pipes\n",
402 		     __FUNCTION__, crtc));
403 		crtcs |= 1 << crtc;
404 		str = end + 1;
405 	}
406 	DBG(("%s: ZaphodPipes=%x\n", __FUNCTION__, crtcs));
407 	return crtcs;
408 }
409 
count_to_mask(int x)410 inline static unsigned count_to_mask(int x)
411 {
412 	return (1 << x) - 1;
413 }
414 
to_sna_output(xf86OutputPtr output)415 static inline struct sna_output *to_sna_output(xf86OutputPtr output)
416 {
417 	return output->driver_private;
418 }
419 
to_connector_id(xf86OutputPtr output)420 static inline int to_connector_id(xf86OutputPtr output)
421 {
422 	assert(to_sna_output(output));
423 	assert(to_sna_output(output)->id);
424 	return to_sna_output(output)->id;
425 }
426 
to_sna_crtc(xf86CrtcPtr crtc)427 static inline struct sna_crtc *to_sna_crtc(xf86CrtcPtr crtc)
428 {
429 	return crtc->driver_private;
430 }
431 
__sna_crtc_pipe(struct sna_crtc * crtc)432 static inline unsigned __sna_crtc_pipe(struct sna_crtc *crtc)
433 {
434 	return crtc->public.flags >> 8 & 0xff;
435 }
436 
__sna_crtc_id(struct sna_crtc * crtc)437 static inline unsigned __sna_crtc_id(struct sna_crtc *crtc)
438 {
439 	return crtc->id;
440 }
441 
sna_crtc_id(xf86CrtcPtr crtc)442 uint32_t sna_crtc_id(xf86CrtcPtr crtc)
443 {
444 	return __sna_crtc_id(to_sna_crtc(crtc));
445 }
446 
event_pending(int fd)447 static inline bool event_pending(int fd)
448 {
449 	struct pollfd pfd;
450 	pfd.fd = fd;
451 	pfd.events = POLLIN;
452 	return poll(&pfd, 1, 0) == 1;
453 }
454 
sna_mode_wait_for_event(struct sna * sna)455 static bool sna_mode_wait_for_event(struct sna *sna)
456 {
457 	struct pollfd pfd;
458 	pfd.fd = sna->kgem.fd;
459 	pfd.events = POLLIN;
460 	return poll(&pfd, 1, -1) == 1;
461 }
462 
fb_id(struct kgem_bo * bo)463 static inline uint32_t fb_id(struct kgem_bo *bo)
464 {
465 	return bo->delta;
466 }
467 
sna_crtc_count_sprites(xf86CrtcPtr crtc)468 unsigned sna_crtc_count_sprites(xf86CrtcPtr crtc)
469 {
470 	struct plane *sprite;
471 	unsigned count;
472 
473 	count = 0;
474 	list_for_each_entry(sprite, &to_sna_crtc(crtc)->sprites, link)
475 		count++;
476 
477 	return count;
478 }
479 
lookup_sprite(struct sna_crtc * crtc,unsigned idx)480 static struct plane *lookup_sprite(struct sna_crtc *crtc, unsigned idx)
481 {
482 	struct plane *sprite;
483 
484 	list_for_each_entry(sprite, &crtc->sprites, link)
485 		if (idx-- == 0)
486 			return sprite;
487 
488 	return NULL;
489 }
490 
sna_crtc_to_sprite(xf86CrtcPtr crtc,unsigned idx)491 uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx)
492 {
493 	struct plane *sprite;
494 
495 	assert(to_sna_crtc(crtc));
496 
497 	sprite = lookup_sprite(to_sna_crtc(crtc), idx);
498 	return sprite ? sprite->id : 0;
499 }
500 
sna_crtc_is_transformed(xf86CrtcPtr crtc)501 bool sna_crtc_is_transformed(xf86CrtcPtr crtc)
502 {
503 	assert(to_sna_crtc(crtc));
504 	return to_sna_crtc(crtc)->transform;
505 }
506 
msc64(struct sna_crtc * sna_crtc,uint32_t seq,uint64_t * msc)507 static inline bool msc64(struct sna_crtc *sna_crtc, uint32_t seq, uint64_t *msc)
508 {
509 	bool record = true;
510 	if (seq < sna_crtc->last_seq) {
511 		if (sna_crtc->last_seq - seq > 0x40000000) {
512 			sna_crtc->wrap_seq++;
513 			DBG(("%s: pipe=%d wrapped; was %u, now %u, wraps=%u\n",
514 			     __FUNCTION__, __sna_crtc_pipe(sna_crtc),
515 			     sna_crtc->last_seq, seq, sna_crtc->wrap_seq));
516 		} else {
517 			DBG(("%s: pipe=%d msc went backwards; was %u, now %u; ignoring for last_swap\n",
518 			     __FUNCTION__, __sna_crtc_pipe(sna_crtc), sna_crtc->last_seq, seq));
519 
520 			record = false;
521 		}
522 	}
523 	*msc = (uint64_t)sna_crtc->wrap_seq << 32 | seq;
524 	return record;
525 }
526 
sna_crtc_record_swap(xf86CrtcPtr crtc,int tv_sec,int tv_usec,unsigned seq)527 uint64_t sna_crtc_record_swap(xf86CrtcPtr crtc,
528 			      int tv_sec, int tv_usec, unsigned seq)
529 {
530 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
531 	uint64_t msc;
532 
533 	assert(sna_crtc);
534 
535 	if (msc64(sna_crtc, seq, &msc)) {
536 		DBG(("%s: recording last swap on pipe=%d, frame %d [msc=%08lld], time %d.%06d\n",
537 		     __FUNCTION__, __sna_crtc_pipe(sna_crtc), seq, (long long)msc,
538 		     tv_sec, tv_usec));
539 		sna_crtc->swap.tv_sec = tv_sec;
540 		sna_crtc->swap.tv_usec = tv_usec;
541 		sna_crtc->swap.msc = msc;
542 	} else {
543 		DBG(("%s: swap event on pipe=%d, frame %d [msc=%08lld], time %d.%06d\n",
544 		     __FUNCTION__, __sna_crtc_pipe(sna_crtc), seq, (long long)msc,
545 		     tv_sec, tv_usec));
546 	}
547 
548 	return msc;
549 }
550 
sna_crtc_last_swap(xf86CrtcPtr crtc)551 const struct ust_msc *sna_crtc_last_swap(xf86CrtcPtr crtc)
552 {
553 	static struct ust_msc zero;
554 
555 	if (crtc == NULL) {
556 		return &zero;
557 	} else {
558 		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
559 		assert(sna_crtc);
560 		return &sna_crtc->swap;
561 	}
562 }
563 
564 #ifndef NDEBUG
565 static void gem_close(int fd, uint32_t handle);
assert_scanout(struct kgem * kgem,struct kgem_bo * bo,int width,int height)566 static void assert_scanout(struct kgem *kgem, struct kgem_bo *bo,
567 			   int width, int height)
568 {
569 	struct drm_mode_fb_cmd info;
570 
571 	assert(bo->scanout);
572 
573 	VG_CLEAR(info);
574 	info.fb_id = fb_id(bo);
575 
576 	assert(drmIoctl(kgem->fd, DRM_IOCTL_MODE_GETFB, &info) == 0);
577 	gem_close(kgem->fd, info.handle);
578 
579 	assert(width <= info.width && height <= info.height);
580 }
581 #else
582 #define assert_scanout(k, b, w, h)
583 #endif
584 
assert_crtc_fb(struct sna * sna,struct sna_crtc * crtc)585 static void assert_crtc_fb(struct sna *sna, struct sna_crtc *crtc)
586 {
587 #ifndef NDEBUG
588 	struct drm_mode_crtc mode = { .crtc_id = __sna_crtc_id(crtc) };
589 	drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode);
590 	assert(mode.fb_id == fb_id(crtc->bo));
591 #endif
592 }
593 
get_fb(struct sna * sna,struct kgem_bo * bo,int width,int height)594 static unsigned get_fb(struct sna *sna, struct kgem_bo *bo,
595 		       int width, int height)
596 {
597 	ScrnInfoPtr scrn = sna->scrn;
598 	struct drm_mode_fb_cmd arg;
599 
600 	if (!kgem_bo_is_fenced(&sna->kgem, bo))
601 		return 0;
602 
603 	assert(bo->refcnt);
604 	assert(bo->proxy == NULL);
605 	assert(!bo->snoop);
606 	assert(8*bo->pitch >= width * scrn->bitsPerPixel);
607 	assert(height * bo->pitch <= kgem_bo_size(bo)); /* XXX crtc offset */
608 	if (fb_id(bo)) {
609 		DBG(("%s: reusing fb=%d for handle=%d\n",
610 		     __FUNCTION__, fb_id(bo), bo->handle));
611 		assert_scanout(&sna->kgem, bo, width, height);
612 		return fb_id(bo);
613 	}
614 
615 	DBG(("%s: create fb %dx%d@%d/%d\n",
616 	     __FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel));
617 
618 	assert(bo->tiling != I915_TILING_Y || sna->kgem.can_scanout_y);
619 	assert((bo->pitch & 63) == 0);
620 	assert(scrn->vtSema); /* must be master */
621 
622 	VG_CLEAR(arg);
623 	arg.width = width;
624 	arg.height = height;
625 	arg.pitch = bo->pitch;
626 	arg.bpp = scrn->bitsPerPixel;
627 	arg.depth = scrn->depth;
628 	arg.handle = bo->handle;
629 
630 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_ADDFB, &arg)) {
631 		/* Try again with the fancy version */
632 		struct local_mode_fb_cmd2 {
633 			uint32_t fb_id;
634 			uint32_t width, height;
635 			uint32_t pixel_format;
636 			uint32_t flags;
637 
638 			uint32_t handles[4];
639 			uint32_t pitches[4]; /* pitch for each plane */
640 			uint32_t offsets[4]; /* offset of each plane */
641 			uint64_t modifiers[4];
642 		} f;
643 #define LOCAL_IOCTL_MODE_ADDFB2 DRM_IOWR(0xb8, struct local_mode_fb_cmd2)
644 		memset(&f, 0, sizeof(f));
645 		f.width = width;
646 		f.height = height;
647 		/* XXX interlaced */
648 		f.flags = 1 << 1; /* +modifiers */
649 		f.handles[0] = bo->handle;
650 		f.pitches[0] = bo->pitch;
651 
652 		switch (bo->tiling) {
653 		case I915_TILING_NONE:
654 			break;
655 		case I915_TILING_X:
656 			/* I915_FORMAT_MOD_X_TILED */
657 			f.modifiers[0] = (uint64_t)1 << 56 | 1;
658 			break;
659 		case I915_TILING_Y:
660 			/* I915_FORMAT_MOD_X_TILED */
661 			f.modifiers[0] = (uint64_t)1 << 56 | 2;
662 			break;
663 		}
664 
665 #define fourcc(a,b,c,d) ((a) | (b) << 8 | (c) << 16 | (d) << 24)
666 		switch (scrn->depth) {
667 		default:
668 			ERR(("%s: unhandled screen format, depth=%d\n",
669 			     __FUNCTION__, scrn->depth));
670 			goto fail;
671 		case 8:
672 			f.pixel_format = fourcc('C', '8', ' ', ' ');
673 			break;
674 		case 15:
675 			f.pixel_format = fourcc('X', 'R', '1', '5');
676 			break;
677 		case 16:
678 			f.pixel_format = fourcc('R', 'G', '1', '6');
679 			break;
680 		case 24:
681 			f.pixel_format = fourcc('X', 'R', '2', '4');
682 			break;
683 		case 30:
684 			f.pixel_format = fourcc('X', 'R', '3', '0');
685 			break;
686 		}
687 #undef fourcc
688 
689 		if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_ADDFB2, &f)) {
690 fail:
691 			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
692 				   "%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d: %d\n",
693 				   __FUNCTION__, width, height,
694 				   scrn->depth, scrn->bitsPerPixel, bo->pitch, errno);
695 			return 0;
696 		}
697 
698 		arg.fb_id = f.fb_id;
699 	}
700 	assert(arg.fb_id != 0);
701 	bo->delta = arg.fb_id;
702 	DBG(("%s: attached fb=%d to handle=%d\n",
703 	     __FUNCTION__, bo->delta, arg.handle));
704 
705 	bo->scanout = true;
706 	return bo->delta;
707 }
708 
gem_create(int fd,int size)709 static uint32_t gem_create(int fd, int size)
710 {
711 	struct drm_i915_gem_create create;
712 
713 	assert((size & 4095) == 0);
714 
715 	VG_CLEAR(create);
716 	create.handle = 0;
717 	create.size = size;
718 	(void)drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
719 
720 	return create.handle;
721 }
722 
gem_mmap(int fd,int handle,int size)723 static void *gem_mmap(int fd, int handle, int size)
724 {
725 	struct drm_i915_gem_mmap_gtt mmap_arg;
726 	struct drm_i915_gem_set_domain set_domain;
727 	void *ptr;
728 
729 	VG_CLEAR(mmap_arg);
730 	mmap_arg.handle = handle;
731 	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg))
732 		return NULL;
733 
734 	ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_arg.offset);
735 	if (ptr == MAP_FAILED)
736 		return NULL;
737 
738 	VG_CLEAR(set_domain);
739 	set_domain.handle = handle;
740 	set_domain.read_domains = I915_GEM_DOMAIN_GTT;
741 	set_domain.write_domain = I915_GEM_DOMAIN_GTT;
742 	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
743 		munmap(ptr, size);
744 		return NULL;
745 	}
746 
747 	return ptr;
748 }
749 
gem_close(int fd,uint32_t handle)750 static void gem_close(int fd, uint32_t handle)
751 {
752 	struct drm_gem_close close;
753 
754 	VG_CLEAR(close);
755 	close.handle = handle;
756 	(void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &close);
757 }
758 
759 #define BACKLIGHT_NAME             "Backlight"
760 #define BACKLIGHT_DEPRECATED_NAME  "BACKLIGHT"
761 static Atom backlight_atom, backlight_deprecated_atom;
762 
763 #if HAVE_UDEV
764 static void
sna_backlight_uevent(int fd,void * closure)765 sna_backlight_uevent(int fd, void *closure)
766 {
767 	struct sna *sna = closure;
768 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
769 	int i;
770 
771 	DBG(("%s()\n", __FUNCTION__));
772 
773 	/* Drain the event queue */
774 	while (event_pending(fd)) {
775 		struct udev_device *dev;
776 
777 		DBG(("%s: waiting for uevent\n", __FUNCTION__));
778 		dev = udev_monitor_receive_device(sna->mode.backlight_monitor);
779 		if (dev == NULL)
780 			break;
781 
782 		udev_device_unref(dev);
783 	}
784 
785 	/* Query all backlights for any changes */
786 	DBG(("%s: probing backlights for changes\n", __FUNCTION__));
787 	for (i = 0; i < sna->mode.num_real_output; i++) {
788 		xf86OutputPtr output = config->output[i];
789 		struct sna_output *sna_output = to_sna_output(output);
790 		int val;
791 
792 		if (sna_output->dpms_mode != DPMSModeOn)
793 			continue;
794 
795 		val = backlight_get(&sna_output->backlight);
796 		if (val < 0)
797 			continue;
798 		DBG(("%s(%s): backlight '%s' was %d, now %d\n",
799 		     __FUNCTION__, output->name, sna_output->backlight.iface,
800 		     sna_output->backlight_active_level, val));
801 
802 		if (val == sna_output->backlight_active_level)
803 			continue;
804 
805 		sna_output->backlight_active_level = val;
806 
807 		if (output->randr_output) {
808 			DBG(("%s(%s): sending change notification\n", __FUNCTION__, output->name));
809 			RRChangeOutputProperty(output->randr_output,
810 					       backlight_atom, XA_INTEGER,
811 					       32, PropModeReplace, 1, &val,
812 					       TRUE, FALSE);
813 			RRChangeOutputProperty(output->randr_output,
814 					       backlight_deprecated_atom, XA_INTEGER,
815 					       32, PropModeReplace, 1, &val,
816 					       TRUE, FALSE);
817 		}
818 	}
819 	DBG(("%s: complete\n", __FUNCTION__));
820 }
821 
sna_backlight_pre_init(struct sna * sna)822 static void sna_backlight_pre_init(struct sna *sna)
823 {
824 	struct udev *u;
825 	struct udev_monitor *mon;
826 
827 #if !USE_BACKLIGHT
828 	return;
829 #endif
830 
831 	u = udev_new();
832 	if (!u)
833 		return;
834 
835 	mon = udev_monitor_new_from_netlink(u, "udev");
836 	if (!mon)
837 		goto free_udev;
838 
839 	if (udev_monitor_filter_add_match_subsystem_devtype(mon, "backlight", NULL))
840 		goto free_monitor;
841 
842 	if (udev_monitor_enable_receiving(mon))
843 		goto free_monitor;
844 
845 	sna->mode.backlight_handler =
846 		xf86AddGeneralHandler(udev_monitor_get_fd(mon),
847 				      sna_backlight_uevent, sna);
848 	if (!sna->mode.backlight_handler)
849 		goto free_monitor;
850 
851 	DBG(("%s: installed backlight monitor\n", __FUNCTION__));
852 	sna->mode.backlight_monitor = mon;
853 
854 	return;
855 
856 free_monitor:
857 	udev_monitor_unref(mon);
858 free_udev:
859 	udev_unref(u);
860 }
861 
sna_backlight_drain_uevents(struct sna * sna)862 static void sna_backlight_drain_uevents(struct sna *sna)
863 {
864 	if (sna->mode.backlight_monitor == NULL)
865 		return;
866 
867 	DBG(("%s()\n", __FUNCTION__));
868 	sna_backlight_uevent(udev_monitor_get_fd(sna->mode.backlight_monitor),
869 			     sna);
870 }
871 
sna_backlight_close(struct sna * sna)872 static void sna_backlight_close(struct sna *sna)
873 {
874 	struct udev *u;
875 
876 	if (sna->mode.backlight_handler == NULL)
877 		return;
878 
879 	xf86RemoveGeneralHandler(sna->mode.backlight_handler);
880 
881 	u = udev_monitor_get_udev(sna->mode.backlight_monitor);
882 	udev_monitor_unref(sna->mode.backlight_monitor);
883 	udev_unref(u);
884 
885 	sna->mode.backlight_handler = NULL;
886 	sna->mode.backlight_monitor = NULL;
887 }
888 #else
sna_backlight_pre_init(struct sna * sna)889 static void sna_backlight_pre_init(struct sna *sna) { }
sna_backlight_drain_uevents(struct sna * sna)890 static void sna_backlight_drain_uevents(struct sna *sna) { }
sna_backlight_close(struct sna * sna)891 static void sna_backlight_close(struct sna *sna) { }
892 #endif
893 
894 static void
sna_output_backlight_disable(struct sna_output * sna_output)895 sna_output_backlight_disable(struct sna_output *sna_output)
896 {
897 	xf86OutputPtr output = sna_output->base;
898 
899 	xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
900 		   "Failed to set backlight %s for output %s, disabling\n",
901 		   sna_output->backlight.iface, output->name);
902 	backlight_disable(&sna_output->backlight);
903 	if (output->randr_output) {
904 		RRDeleteOutputProperty(output->randr_output, backlight_atom);
905 		RRDeleteOutputProperty(output->randr_output, backlight_deprecated_atom);
906 	}
907 }
908 
909 static int
sna_output_backlight_set(struct sna_output * sna_output,int level)910 sna_output_backlight_set(struct sna_output *sna_output, int level)
911 {
912 	int ret = 0;
913 
914 	DBG(("%s(%s) level=%d, max=%d\n", __FUNCTION__,
915 	     sna_output->base->name, level, sna_output->backlight.max));
916 
917 	if (backlight_set(&sna_output->backlight, level)) {
918 		sna_output_backlight_disable(sna_output);
919 		ret = -1;
920 	}
921 
922 	/* Consume the uevent notification now so that we don't misconstrue
923 	 * the change latter when we wake up and the output is in a different
924 	 * state.
925 	 */
926 	sna_backlight_drain_uevents(to_sna(sna_output->base->scrn));
927 	return ret;
928 }
929 
930 static bool
has_native_backlight(struct sna_output * sna_output)931 has_native_backlight(struct sna_output *sna_output)
932 {
933 	return sna_output->backlight.type == BL_RAW;
934 }
935 
936 static void
sna_output_backlight_off(struct sna_output * sna_output)937 sna_output_backlight_off(struct sna_output *sna_output)
938 {
939 	/* Trust the kernel to turn the native backlight off. However, we
940 	 * do explicitly turn the backlight back on (when we wake the output)
941 	 * just in case a third party turns it off!
942 	 */
943 	if (has_native_backlight(sna_output))
944 		return;
945 
946 	DBG(("%s(%s)\n", __FUNCTION__, sna_output->base->name));
947 	backlight_off(&sna_output->backlight);
948 	sna_output_backlight_set(sna_output, 0);
949 }
950 
951 static void
sna_output_backlight_on(struct sna_output * sna_output)952 sna_output_backlight_on(struct sna_output *sna_output)
953 {
954 	DBG(("%s(%s)\n", __FUNCTION__, sna_output->base->name));
955 	sna_output_backlight_set(sna_output,
956 				 sna_output->backlight_active_level);
957 	if (backlight_on(&sna_output->backlight) < 0)
958 		sna_output_backlight_disable(sna_output);
959 }
960 
961 static int
sna_output_backlight_get(xf86OutputPtr output)962 sna_output_backlight_get(xf86OutputPtr output)
963 {
964 	struct sna_output *sna_output = output->driver_private;
965 	int level = backlight_get(&sna_output->backlight);
966 	DBG(("%s(%s) level=%d, max=%d\n", __FUNCTION__,
967 	     output->name, level, sna_output->backlight.max));
968 	return level;
969 }
970 
971 static char *
has_user_backlight_override(xf86OutputPtr output)972 has_user_backlight_override(xf86OutputPtr output)
973 {
974 	struct sna *sna = to_sna(output->scrn);
975 	const char *str;
976 
977 	str = xf86GetOptValString(sna->Options, OPTION_BACKLIGHT);
978 	if (str == NULL)
979 		return NULL;
980 
981 	DBG(("%s(%s) requested %s\n", __FUNCTION__, output->name, str));
982 	if (*str == '\0')
983 		return (char *)str;
984 
985 	if (!backlight_exists(str)) {
986 		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
987 			   "Unrecognised backlight control interface '%s'\n",
988 			   str);
989 		return NULL;
990 	}
991 
992 	return strdup(str);
993 }
994 
get_device_minor(int fd)995 static int get_device_minor(int fd)
996 {
997 	struct stat st;
998 
999 	if (fstat(fd, &st) || !S_ISCHR(st.st_mode))
1000 		return -1;
1001 
1002 	return st.st_rdev & 0x63;
1003 }
1004 
1005 static const char * const sysfs_connector_types[] = {
1006 	/* DRM_MODE_CONNECTOR_Unknown */	"Unknown",
1007 	/* DRM_MODE_CONNECTOR_VGA */		"VGA",
1008 	/* DRM_MODE_CONNECTOR_DVII */		"DVI-I",
1009 	/* DRM_MODE_CONNECTOR_DVID */		"DVI-D",
1010 	/* DRM_MODE_CONNECTOR_DVIA */		"DVI-A",
1011 	/* DRM_MODE_CONNECTOR_Composite */	"Composite",
1012 	/* DRM_MODE_CONNECTOR_SVIDEO */		"SVIDEO",
1013 	/* DRM_MODE_CONNECTOR_LVDS */		"LVDS",
1014 	/* DRM_MODE_CONNECTOR_Component */	"Component",
1015 	/* DRM_MODE_CONNECTOR_9PinDIN */	"DIN",
1016 	/* DRM_MODE_CONNECTOR_DisplayPort */	"DP",
1017 	/* DRM_MODE_CONNECTOR_HDMIA */		"HDMI-A",
1018 	/* DRM_MODE_CONNECTOR_HDMIB */		"HDMI-B",
1019 	/* DRM_MODE_CONNECTOR_TV */		"TV",
1020 	/* DRM_MODE_CONNECTOR_eDP */		"eDP",
1021 	/* DRM_MODE_CONNECTOR_VIRTUAL */	"Virtual",
1022 	/* DRM_MODE_CONNECTOR_DSI */		"DSI",
1023 	/* DRM_MODE_CONNECTOR_DPI */		"DPI"
1024 };
1025 
has_connector_backlight(xf86OutputPtr output)1026 static char *has_connector_backlight(xf86OutputPtr output)
1027 {
1028 	struct sna_output *sna_output = output->driver_private;
1029 	struct sna *sna = to_sna(output->scrn);
1030 	char path[1024];
1031 	DIR *dir;
1032 	struct dirent *de;
1033 	int minor, len;
1034 	char *str = NULL;
1035 
1036 	if (sna_output->connector_type >= ARRAY_SIZE(sysfs_connector_types))
1037 		return NULL;
1038 
1039 	minor = get_device_minor(sna->kgem.fd);
1040 	if (minor < 0)
1041 		return NULL;
1042 
1043 	len = snprintf(path, sizeof(path),
1044 		       "/sys/class/drm/card%d-%s-%d",
1045 		       minor,
1046 		       sysfs_connector_types[sna_output->connector_type],
1047 		       sna_output->connector_type_id);
1048 	DBG(("%s: lookup %s\n", __FUNCTION__, path));
1049 
1050 	dir = opendir(path);
1051 	if (dir == NULL)
1052 		return NULL;
1053 
1054 	while ((de = readdir(dir))) {
1055 		struct stat st;
1056 
1057 		if (*de->d_name == '.')
1058 			continue;
1059 
1060 		snprintf(path + len, sizeof(path) - len,
1061 			 "/%s", de->d_name);
1062 
1063 		if (stat(path, &st))
1064 			continue;
1065 
1066 		if (!S_ISDIR(st.st_mode))
1067 			continue;
1068 
1069 		DBG(("%s: testing %s as backlight\n",
1070 		     __FUNCTION__, de->d_name));
1071 
1072 		if (backlight_exists(de->d_name)) {
1073 			str = strdup(de->d_name); /* leak! */
1074 			break;
1075 		}
1076 	}
1077 
1078 	closedir(dir);
1079 	return str;
1080 }
1081 
1082 static void
sna_output_backlight_init(xf86OutputPtr output)1083 sna_output_backlight_init(xf86OutputPtr output)
1084 {
1085 	struct sna_output *sna_output = output->driver_private;
1086 	struct pci_device *pci;
1087 	MessageType from;
1088 	char *best_iface;
1089 
1090 #if !USE_BACKLIGHT
1091 	return;
1092 #endif
1093 
1094 	if (sna_output->is_panel) {
1095 		from = X_CONFIG;
1096 		best_iface = has_user_backlight_override(output);
1097 		if (best_iface)
1098 			goto done;
1099 	}
1100 
1101 	best_iface = has_connector_backlight(output);
1102 	if (best_iface)
1103 		goto done;
1104 
1105 	if (!sna_output->is_panel)
1106 		return;
1107 
1108 	/* XXX detect right backlight for multi-GPU/panels */
1109 	from = X_PROBED;
1110 	pci = xf86GetPciInfoForEntity(to_sna(output->scrn)->pEnt->index);
1111 	if (pci != NULL)
1112 		best_iface = backlight_find_for_device(pci);
1113 
1114 done:
1115 	DBG(("%s(%s) opening backlight %s\n", __FUNCTION__,
1116 	     output->name, best_iface ?: "none"));
1117 	sna_output->backlight_active_level =
1118 		backlight_open(&sna_output->backlight, best_iface);
1119 	DBG(("%s(%s): initial backlight value %d\n",
1120 	     __FUNCTION__, output->name, sna_output->backlight_active_level));
1121 	if (sna_output->backlight_active_level < 0)
1122 		return;
1123 
1124 	switch (sna_output->backlight.type) {
1125 	case BL_FIRMWARE: best_iface = (char *)"firmware"; break;
1126 	case BL_PLATFORM: best_iface = (char *)"platform"; break;
1127 	case BL_RAW: best_iface = (char *)"raw"; break;
1128 	default: best_iface = (char *)"unknown"; break;
1129 	}
1130 	xf86DrvMsg(output->scrn->scrnIndex, from,
1131 		   "Found backlight control interface %s (type '%s') for output %s\n",
1132 		   sna_output->backlight.iface, best_iface, output->name);
1133 }
1134 
1135 #if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(22, 0)
sigio_block(void)1136 static inline int sigio_block(void)
1137 {
1138 	return 0;
1139 }
sigio_unblock(int was_blocked)1140 static inline void sigio_unblock(int was_blocked)
1141 {
1142 	(void)was_blocked;
1143 }
1144 #elif XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0)
sigio_block(void)1145 static inline int sigio_block(void)
1146 {
1147 	OsBlockSIGIO();
1148 	return 0;
1149 }
sigio_unblock(int was_blocked)1150 static inline void sigio_unblock(int was_blocked)
1151 {
1152 	OsReleaseSIGIO();
1153 	(void)was_blocked;
1154 }
1155 #else
1156 #include <xf86_OSproc.h>
sigio_block(void)1157 static inline int sigio_block(void)
1158 {
1159 	return xf86BlockSIGIO();
1160 }
sigio_unblock(int was_blocked)1161 static inline void sigio_unblock(int was_blocked)
1162 {
1163 	xf86UnblockSIGIO(was_blocked);
1164 }
1165 #endif
1166 
canonical_kmode_name(const struct drm_mode_modeinfo * kmode)1167 static char *canonical_kmode_name(const struct drm_mode_modeinfo *kmode)
1168 {
1169 	char tmp[32], *buf;
1170 	int len;
1171 
1172 	len = sprintf(tmp, "%dx%d%s",
1173 		      kmode->hdisplay, kmode->vdisplay,
1174 		      kmode->flags & V_INTERLACE ? "i" : "");
1175 	if ((unsigned)len >= sizeof(tmp))
1176 		return NULL;
1177 
1178 	buf = malloc(len + 1);
1179 	if (buf == NULL)
1180 		return NULL;
1181 
1182 	return memcpy(buf, tmp, len + 1);
1183 }
1184 
get_kmode_name(const struct drm_mode_modeinfo * kmode)1185 static char *get_kmode_name(const struct drm_mode_modeinfo *kmode)
1186 {
1187 	if (*kmode->name == '\0')
1188 		return canonical_kmode_name(kmode);
1189 
1190 	return strdup(kmode->name);
1191 }
1192 
1193 static DisplayModePtr
mode_from_kmode(ScrnInfoPtr scrn,const struct drm_mode_modeinfo * kmode,DisplayModePtr mode)1194 mode_from_kmode(ScrnInfoPtr scrn,
1195 		const struct drm_mode_modeinfo *kmode,
1196 		DisplayModePtr mode)
1197 {
1198 	DBG(("kmode: %s, clock=%d, %d %d %d %d %d, %d %d %d %d %d, flags=%x, type=%x\n",
1199 	     kmode->name, kmode->clock,
1200 	     kmode->hdisplay, kmode->hsync_start, kmode->hsync_end, kmode->htotal, kmode->hskew,
1201 	     kmode->vdisplay, kmode->vsync_start, kmode->vsync_end, kmode->vtotal, kmode->vscan,
1202 	     kmode->flags, kmode->type));
1203 
1204 	mode->status = MODE_OK;
1205 
1206 	mode->Clock = kmode->clock;
1207 
1208 	mode->HDisplay = kmode->hdisplay;
1209 	mode->HSyncStart = kmode->hsync_start;
1210 	mode->HSyncEnd = kmode->hsync_end;
1211 	mode->HTotal = kmode->htotal;
1212 	mode->HSkew = kmode->hskew;
1213 
1214 	mode->VDisplay = kmode->vdisplay;
1215 	mode->VSyncStart = kmode->vsync_start;
1216 	mode->VSyncEnd = kmode->vsync_end;
1217 	mode->VTotal = kmode->vtotal;
1218 	mode->VScan = kmode->vscan;
1219 
1220 	mode->VRefresh = kmode->vrefresh;
1221 	mode->Flags = kmode->flags;
1222 	mode->name = get_kmode_name(kmode);
1223 
1224 	if (kmode->type & DRM_MODE_TYPE_DRIVER)
1225 		mode->type = M_T_DRIVER;
1226 	if (kmode->type & DRM_MODE_TYPE_PREFERRED)
1227 		mode->type |= M_T_PREFERRED;
1228 
1229 	if (mode->status == MODE_OK && kmode->flags & ~KNOWN_MODE_FLAGS)
1230 		mode->status = MODE_BAD; /* unknown flags => unhandled */
1231 
1232 	xf86SetModeCrtc(mode, scrn->adjustFlags);
1233 	return mode;
1234 }
1235 
1236 static void
mode_to_kmode(struct drm_mode_modeinfo * kmode,DisplayModePtr mode)1237 mode_to_kmode(struct drm_mode_modeinfo *kmode, DisplayModePtr mode)
1238 {
1239 	memset(kmode, 0, sizeof(*kmode));
1240 
1241 	kmode->clock = mode->Clock;
1242 	kmode->hdisplay = mode->HDisplay;
1243 	kmode->hsync_start = mode->HSyncStart;
1244 	kmode->hsync_end = mode->HSyncEnd;
1245 	kmode->htotal = mode->HTotal;
1246 	kmode->hskew = mode->HSkew;
1247 
1248 	kmode->vdisplay = mode->VDisplay;
1249 	kmode->vsync_start = mode->VSyncStart;
1250 	kmode->vsync_end = mode->VSyncEnd;
1251 	kmode->vtotal = mode->VTotal;
1252 	kmode->vscan = mode->VScan;
1253 
1254 	kmode->vrefresh = mode->VRefresh;
1255 	kmode->flags = mode->Flags;
1256 	if (mode->name)
1257 		strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
1258 	kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1259 }
1260 
1261 static void
sna_crtc_force_outputs_on(xf86CrtcPtr crtc)1262 sna_crtc_force_outputs_on(xf86CrtcPtr crtc)
1263 {
1264 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
1265 	/* All attached outputs are valid, so update our timestamps */
1266 	unsigned now = GetTimeInMillis();
1267 	int i;
1268 
1269 	assert(to_sna_crtc(crtc));
1270 	DBG(("%s(pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc)));
1271 
1272 	/* DPMS handling by the kernel is inconsistent, so after setting a
1273 	 * mode on an output presume that we intend for it to be on, or that
1274 	 * the kernel will force it on.
1275 	 *
1276 	 * So force DPMS to be on for all connected outputs, and restore
1277 	 * the backlight.
1278 	 */
1279 	for (i = 0; i < config->num_output; i++) {
1280 		xf86OutputPtr output = config->output[i];
1281 
1282 		if (output->crtc != crtc)
1283 			continue;
1284 
1285 		__sna_output_dpms(output, DPMSModeOn, false);
1286 		if (to_sna_output(output)->last_detect)
1287 			to_sna_output(output)->last_detect = now;
1288 	}
1289 
1290 #if XF86_CRTC_VERSION >= 3
1291 	crtc->active = TRUE;
1292 #endif
1293 }
1294 
1295 static void
sna_crtc_force_outputs_off(xf86CrtcPtr crtc)1296 sna_crtc_force_outputs_off(xf86CrtcPtr crtc)
1297 {
1298 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
1299 	int i;
1300 
1301 	assert(to_sna_crtc(crtc));
1302 	DBG(("%s(pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc)));
1303 
1304 	/* DPMS handling by the kernel is inconsistent, so after setting a
1305 	 * mode on an output presume that we intend for it to be on, or that
1306 	 * the kernel will force it on.
1307 	 *
1308 	 * So force DPMS to be on for all connected outputs, and restore
1309 	 * the backlight.
1310 	 */
1311 	for (i = 0; i < config->num_output; i++) {
1312 		xf86OutputPtr output = config->output[i];
1313 
1314 		if (output->crtc != crtc)
1315 			continue;
1316 
1317 		__sna_output_dpms(output, DPMSModeOff, false);
1318 	}
1319 }
1320 
1321 static unsigned
rotation_reflect(unsigned rotation)1322 rotation_reflect(unsigned rotation)
1323 {
1324 	unsigned other_bits;
1325 
1326 	/* paranoia for future extensions */
1327 	other_bits = rotation & ~RR_Rotate_All;
1328 
1329 	/* flip the reflection to compensate for reflecting the rotation */
1330 	other_bits ^= RR_Reflect_X | RR_Reflect_Y;
1331 
1332 	/* Reflect the screen by rotating the rotation bit,
1333 	 * which has to have at least RR_Rotate_0 set. This allows
1334 	 * us to reflect any of the rotation bits, not just 0.
1335 	 */
1336 	rotation &= RR_Rotate_All;
1337 	assert(rotation);
1338 	rotation <<= 2; /* RR_Rotate_0 -> RR_Rotate_180 etc */
1339 	rotation |= rotation >> 4; /* RR_Rotate_270' to RR_Rotate_90 */
1340 	rotation &= RR_Rotate_All;
1341 	assert(rotation);
1342 
1343 	return rotation | other_bits;
1344 }
1345 
1346 static unsigned
rotation_reduce(struct plane * p,unsigned rotation)1347 rotation_reduce(struct plane *p, unsigned rotation)
1348 {
1349 	/* If unsupported try exchanging rotation for a reflection */
1350 	if (rotation & ~p->rotation.supported) {
1351 		unsigned new_rotation = rotation_reflect(rotation);
1352 		if ((new_rotation & p->rotation.supported) == new_rotation)
1353 			rotation = new_rotation;
1354 	}
1355 
1356 	/* Only one rotation bit should be set */
1357 	assert(is_power_of_two(rotation & RR_Rotate_All));
1358 
1359 	return rotation;
1360 }
1361 
1362 static bool
rotation_set(struct sna * sna,struct plane * p,uint32_t desired)1363 rotation_set(struct sna *sna, struct plane *p, uint32_t desired)
1364 {
1365 #define LOCAL_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xbA, struct local_mode_obj_set_property)
1366 	struct local_mode_obj_set_property {
1367 		uint64_t value;
1368 		uint32_t prop_id;
1369 		uint32_t obj_id;
1370 		uint32_t obj_type;
1371 		uint32_t pad;
1372 	} prop;
1373 
1374 	if (desired == p->rotation.current)
1375 		return true;
1376 
1377 	if ((desired & p->rotation.supported) != desired) {
1378 		errno = EINVAL;
1379 		return false;
1380 	}
1381 
1382 	DBG(("%s: obj=%d, type=%x prop=%d set-rotation=%x\n",
1383 	     __FUNCTION__, p->id, LOCAL_MODE_OBJECT_PLANE, p->rotation.prop, desired));
1384 
1385 	assert(p->id);
1386 	assert(p->rotation.prop);
1387 
1388 	VG_CLEAR(prop);
1389 	prop.obj_id = p->id;
1390 	prop.obj_type = LOCAL_MODE_OBJECT_PLANE;
1391 	prop.prop_id = p->rotation.prop;
1392 	prop.value = desired;
1393 
1394 	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_SETPROPERTY, &prop))
1395 		return false;
1396 
1397 	p->rotation.current = desired;
1398 	return true;
1399 }
1400 
1401 static void
rotation_reset(struct plane * p)1402 rotation_reset(struct plane *p)
1403 {
1404 	if (p->rotation.prop == 0)
1405 		return;
1406 
1407 	p->rotation.current = 0;
1408 }
1409 
sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc,unsigned idx,uint32_t rotation)1410 bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc,
1411 				  unsigned idx,
1412 				  uint32_t rotation)
1413 {
1414 	struct plane *sprite;
1415 	assert(to_sna_crtc(crtc));
1416 
1417 	sprite = lookup_sprite(to_sna_crtc(crtc), idx);
1418 	if (!sprite)
1419 		return false;
1420 
1421 	DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n",
1422 	     __FUNCTION__,
1423 	     sna_crtc_id(crtc), sna_crtc_pipe(crtc),
1424 	     sprite->id, rotation));
1425 
1426 	return rotation_set(to_sna(crtc->scrn), sprite,
1427 			    rotation_reduce(sprite, rotation));
1428 }
1429 
1430 #if HAS_DEBUG_FULL
1431 #if !HAS_DEBUG_FULL
1432 #define LogF ErrorF
1433 #endif
1434 struct kmsg {
1435 	int fd;
1436 	int saved_loglevel;
1437 };
1438 
kmsg_get_debug(void)1439 static int kmsg_get_debug(void)
1440 {
1441 	int v = -1;
1442 	int fd;
1443 
1444 	fd = open("/sys/module/drm/parameters/debug", O_RDONLY);
1445 	if (fd != -1) {
1446 		char buf[128];
1447 		int len;
1448 
1449 		len = read(fd, buf, sizeof(buf) - 1);
1450 		if (len != -1) {
1451 			buf[len] = '\0';
1452 			v = atoi(buf);
1453 		}
1454 		close(fd);
1455 	}
1456 
1457 	return v;
1458 }
1459 
kmsg_set_debug(int v)1460 static void kmsg_set_debug(int v)
1461 {
1462 	char buf[128];
1463 	int len;
1464 	int fd;
1465 
1466 	len = snprintf(buf, sizeof(buf), "%d\n", v);
1467 
1468 	fd = open("/sys/module/drm/parameters/debug", O_WRONLY);
1469 	if (fd != -1) {
1470 		write(fd, buf, len);
1471 		close(fd);
1472 	}
1473 }
1474 
kmsg_open(struct kmsg * k)1475 static void kmsg_open(struct kmsg *k)
1476 {
1477 	k->saved_loglevel = kmsg_get_debug();
1478 	if (k->saved_loglevel != -1)
1479 		kmsg_set_debug(0xff);
1480 
1481 	k->fd = open("/dev/kmsg", O_RDONLY | O_NONBLOCK);
1482 	if (k->fd != -1)
1483 		lseek(k->fd, 0, SEEK_END);
1484 }
1485 
kmsg_close(struct kmsg * k,int dump)1486 static void kmsg_close(struct kmsg *k, int dump)
1487 {
1488 	FILE *file;
1489 
1490 	file = NULL;
1491 	if (k->fd != -1 && dump)
1492 		file = fdopen(k->fd, "r");
1493 	if (file) {
1494 		size_t len = 0;
1495 		char *line = NULL;
1496 
1497 		while (getline(&line, &len, file) != -1) {
1498 			char *start = strchr(line, ';');
1499 			if (start)
1500 				LogF("KMSG: %s", start + 1);
1501 		}
1502 
1503 		free(line);
1504 		fclose(file);
1505 	}
1506 
1507 	if (k->fd != -1)
1508 		close(k->fd);
1509 
1510 	if (k->saved_loglevel != -1)
1511 		kmsg_set_debug(k->saved_loglevel);
1512 }
1513 #else
1514 struct kmsg { int unused; };
kmsg_open(struct kmsg * k)1515 static void kmsg_open(struct kmsg *k) {}
kmsg_close(struct kmsg * k,int dump)1516 static void kmsg_close(struct kmsg *k, int dump) {}
1517 #endif
1518 
1519 static int
sna_crtc_apply(xf86CrtcPtr crtc)1520 sna_crtc_apply(xf86CrtcPtr crtc)
1521 {
1522 	struct sna *sna = to_sna(crtc->scrn);
1523 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
1524 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
1525 	struct drm_mode_crtc arg;
1526 	uint32_t output_ids[32];
1527 	int output_count = 0;
1528 	int sigio, i;
1529 	struct kmsg kmsg;
1530 	int ret = EINVAL;
1531 
1532 	DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__,
1533 	     __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
1534 	     sna_crtc->bo->handle));
1535 	if (!sna_crtc->kmode.clock) {
1536 		ERR(("%s(CRTC:%d [pipe=%d]): attempted to set an invalid mode\n",
1537 		     __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc)));
1538 		return EINVAL;
1539 	}
1540 
1541 	kmsg_open(&kmsg);
1542 	sigio = sigio_block();
1543 
1544 	assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids));
1545 	sna_crtc_disable_cursor(sna, sna_crtc);
1546 
1547 	if (!rotation_set(sna, &sna_crtc->primary, sna_crtc->rotation)) {
1548 		memset(&arg, 0, sizeof(arg));
1549 		arg.crtc_id = __sna_crtc_id(sna_crtc);
1550 		(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
1551 	}
1552 
1553 	if (!rotation_set(sna, &sna_crtc->primary, sna_crtc->rotation)) {
1554 		ERR(("%s: set-primary-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n",
1555 		     __FUNCTION__, sna_crtc->primary.rotation.prop, sna_crtc->rotation, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), errno));
1556 		sna_crtc->primary.rotation.supported &= ~sna_crtc->rotation;
1557 		goto unblock;
1558 	}
1559 	DBG(("%s: CRTC:%d [pipe=%d] primary rotation set to %x\n",
1560 	     __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), sna_crtc->rotation));
1561 
1562 	for (i = 0; i < sna->mode.num_real_output; i++) {
1563 		xf86OutputPtr output = config->output[i];
1564 
1565 		/* Make sure we mark the output as off (and save the backlight)
1566 		 * before the kernel turns it off due to changing the pipe.
1567 		 * This is necessary as the kernel may turn off the backlight
1568 		 * and we lose track of the user settings.
1569 		 */
1570 		if (output->crtc == NULL)
1571 			__sna_output_dpms(output, DPMSModeOff, false);
1572 
1573 		if (output->crtc != crtc)
1574 			continue;
1575 
1576 		/* Skip over any hotunplugged outputs so that we can
1577 		 * recover in cases where the previous mode is now
1578 		 * only partially valid.
1579 		 */
1580 		if (!to_sna_output(output)->id)
1581 			continue;
1582 
1583 		DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n",
1584 		     __FUNCTION__, output->name, i, to_connector_id(output),
1585 		     __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
1586 		     (uint32_t)output->possible_crtcs,
1587 		     (uint32_t)output->possible_clones));
1588 
1589 		assert(output->possible_crtcs & (1 << __sna_crtc_pipe(sna_crtc)) ||
1590 		       is_zaphod(crtc->scrn));
1591 
1592 		output_ids[output_count] = to_connector_id(output);
1593 		if (++output_count == ARRAY_SIZE(output_ids)) {
1594 			DBG(("%s: too many outputs (%d) for me!\n",
1595 			     __FUNCTION__, output_count));
1596 			goto unblock;
1597 		}
1598 	}
1599 	if (output_count == 0) {
1600 		DBG(("%s: no outputs\n", __FUNCTION__));
1601 		goto unblock;
1602 	}
1603 
1604 	VG_CLEAR(arg);
1605 	arg.crtc_id = __sna_crtc_id(sna_crtc);
1606 	arg.fb_id = fb_id(sna_crtc->bo);
1607 	if (sna_crtc->transform || sna_crtc->slave_pixmap) {
1608 		arg.x = 0;
1609 		arg.y = 0;
1610 		sna_crtc->offset = 0;
1611 	} else {
1612 		arg.x = crtc->x;
1613 		arg.y = crtc->y;
1614 		sna_crtc->offset = arg.y << 16 | arg.x;
1615 	}
1616 	arg.set_connectors_ptr = (uintptr_t)output_ids;
1617 	arg.count_connectors = output_count;
1618 	arg.mode = sna_crtc->kmode;
1619 	arg.mode_valid = 1;
1620 
1621 	DBG(("%s: applying crtc [%d, pipe=%d] mode=%dx%d+%d+%d@%d, fb=%d%s%s update to %d outputs [%d...]\n",
1622 	     __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
1623 	     arg.mode.hdisplay,
1624 	     arg.mode.vdisplay,
1625 	     arg.x, arg.y,
1626 	     arg.mode.clock,
1627 	     arg.fb_id,
1628 	     sna_crtc->shadow ? " [shadow]" : "",
1629 	     sna_crtc->transform ? " [transformed]" : "",
1630 	     output_count, output_count ? output_ids[0] : 0));
1631 
1632 	ret = 0;
1633 	if (unlikely(drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg))) {
1634 		ret = errno;
1635 		goto unblock;
1636 	}
1637 
1638 	sna_crtc->mode_serial++;
1639 	sna_crtc_force_outputs_on(crtc);
1640 
1641 unblock:
1642 	sigio_unblock(sigio);
1643 	kmsg_close(&kmsg, ret);
1644 	return ret;
1645 }
1646 
overlap(const BoxRec * a,const BoxRec * b)1647 static bool overlap(const BoxRec *a, const BoxRec *b)
1648 {
1649 	if (a->x1 >= b->x2)
1650 		return false;
1651 	if (a->x2 <= b->x1)
1652 		return false;
1653 
1654 	if (a->y1 >= b->y2)
1655 		return false;
1656 	if (a->y2 <= b->y1)
1657 		return false;
1658 
1659 	return true;
1660 }
1661 
defer_event(struct sna * sna,struct drm_event * base)1662 static void defer_event(struct sna *sna, struct drm_event *base)
1663 {
1664 	if (sna->mode.shadow_nevent == sna->mode.shadow_size) {
1665 		int size = sna->mode.shadow_size * 2;
1666 		void *ptr;
1667 
1668 		ptr = realloc(sna->mode.shadow_events,
1669 			      sizeof(struct drm_event_vblank)*size);
1670 		if (!ptr)
1671 			return;
1672 
1673 		sna->mode.shadow_events = ptr;
1674 		sna->mode.shadow_size = size;
1675 	}
1676 
1677 	memcpy(&sna->mode.shadow_events[sna->mode.shadow_nevent++],
1678 	       base, sizeof(struct drm_event_vblank));
1679 	DBG(("%s: deferring event count=%d\n",
1680 	     __func__, sna->mode.shadow_nevent));
1681 }
1682 
flush_events(struct sna * sna)1683 static void flush_events(struct sna *sna)
1684 {
1685 	int n;
1686 
1687 	if (!sna->mode.shadow_nevent)
1688 		return;
1689 
1690 	DBG(("%s: flushing %d events=%d\n", __func__, sna->mode.shadow_nevent));
1691 
1692 	for (n = 0; n < sna->mode.shadow_nevent; n++) {
1693 		struct drm_event_vblank *vb = &sna->mode.shadow_events[n];
1694 
1695 		if ((uintptr_t)(vb->user_data) & 2)
1696 			sna_present_vblank_handler(vb);
1697 		else
1698 			sna_dri2_vblank_handler(vb);
1699 	}
1700 
1701 	sna->mode.shadow_nevent = 0;
1702 }
1703 
1704 
wait_for_shadow(struct sna * sna,struct sna_pixmap * priv,unsigned flags)1705 static bool wait_for_shadow(struct sna *sna,
1706 			    struct sna_pixmap *priv,
1707 			    unsigned flags)
1708 {
1709 	PixmapPtr pixmap = priv->pixmap;
1710 	struct kgem_bo *bo, *tmp;
1711 	int flip_active;
1712 	bool ret = true;
1713 
1714 	DBG(("%s: enabled? %d flags=%x, flips=%d, pixmap=%ld [front?=%d], handle=%d, shadow=%d\n",
1715 	     __FUNCTION__, sna->mode.shadow_enabled,
1716 	     flags, sna->mode.flip_active,
1717 	     pixmap->drawable.serialNumber, pixmap == sna->front,
1718 	     priv->gpu_bo->handle, sna->mode.shadow->handle));
1719 
1720 	assert(priv->move_to_gpu_data == sna);
1721 	assert(sna->mode.shadow != priv->gpu_bo);
1722 
1723 	if (flags == 0 || pixmap != sna->front || !sna->mode.shadow_enabled)
1724 		goto done;
1725 
1726 	assert(sna->mode.shadow_damage);
1727 
1728 	if ((flags & MOVE_WRITE) == 0) {
1729 		if ((flags & __MOVE_SCANOUT) == 0) {
1730 			struct sna_crtc *crtc;
1731 
1732 			list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link) {
1733 				if (overlap(&sna->mode.shadow_region.extents,
1734 					    &crtc->base->bounds)) {
1735 					DrawableRec draw;
1736 					RegionRec region;
1737 
1738 					draw.width = crtc->base->mode.HDisplay;
1739 					draw.height = crtc->base->mode.VDisplay;
1740 					draw.depth = sna->front->drawable.depth;
1741 					draw.bitsPerPixel = sna->front->drawable.bitsPerPixel;
1742 
1743 					DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n",
1744 					     __FUNCTION__,
1745 					     crtc->base->bounds.x1,
1746 					     crtc->base->bounds.y1,
1747 					     crtc->base->bounds.x2,
1748 					     crtc->base->bounds.y2,
1749 					     crtc->client_bo->handle));
1750 
1751 					ret &= sna->render.copy_boxes(sna, GXcopy,
1752 								      &draw, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
1753 								      &pixmap->drawable, priv->gpu_bo, 0, 0,
1754 								      &crtc->base->bounds, 1,
1755 								      0);
1756 
1757 					region.extents = crtc->base->bounds;
1758 					region.data = NULL;
1759 					RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, &region);
1760 				}
1761 			}
1762 		}
1763 
1764 		return ret;
1765 	}
1766 
1767 	assert(sna->mode.shadow_active);
1768 
1769 	flip_active = sna->mode.flip_active;
1770 	if (flip_active) {
1771 		struct sna_crtc *crtc;
1772 		list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link)
1773 			flip_active -= crtc->flip_pending;
1774 		DBG(("%s: %d flips still pending, shadow flip_active=%d\n",
1775 		     __FUNCTION__, sna->mode.flip_active, flip_active));
1776 	}
1777 
1778 	bo = sna->mode.shadow;
1779 	if (flip_active) {
1780 		bo = kgem_create_2d(&sna->kgem,
1781 				    pixmap->drawable.width,
1782 				    pixmap->drawable.height,
1783 				    pixmap->drawable.bitsPerPixel,
1784 				    priv->gpu_bo->tiling,
1785 				    CREATE_EXACT | CREATE_SCANOUT);
1786 		if (bo == NULL)
1787 			return false;
1788 
1789 		DBG(("%s: replacing still-attached GPU bo handle=%d, flips=%d\n",
1790 		     __FUNCTION__, priv->gpu_bo->tiling, sna->mode.flip_active));
1791 
1792 		RegionUninit(&sna->mode.shadow_region);
1793 		sna->mode.shadow_region.extents.x1 = 0;
1794 		sna->mode.shadow_region.extents.y1 = 0;
1795 		sna->mode.shadow_region.extents.x2 = pixmap->drawable.width;
1796 		sna->mode.shadow_region.extents.y2 = pixmap->drawable.height;
1797 		sna->mode.shadow_region.data = NULL;
1798 	}
1799 
1800 	if (bo->refcnt > 1) {
1801 		bo = kgem_create_2d(&sna->kgem,
1802 				    pixmap->drawable.width,
1803 				    pixmap->drawable.height,
1804 				    pixmap->drawable.bitsPerPixel,
1805 				    priv->gpu_bo->tiling,
1806 				    CREATE_EXACT | CREATE_SCANOUT);
1807 		if (bo != NULL) {
1808 			DBG(("%s: replacing exported GPU bo\n",
1809 			     __FUNCTION__));
1810 
1811 			RegionUninit(&sna->mode.shadow_region);
1812 			sna->mode.shadow_region.extents.x1 = 0;
1813 			sna->mode.shadow_region.extents.y1 = 0;
1814 			sna->mode.shadow_region.extents.x2 = pixmap->drawable.width;
1815 			sna->mode.shadow_region.extents.y2 = pixmap->drawable.height;
1816 			sna->mode.shadow_region.data = NULL;
1817 		} else
1818 			bo = sna->mode.shadow;
1819 	}
1820 
1821 	RegionSubtract(&sna->mode.shadow_region,
1822 		       &sna->mode.shadow_region,
1823 		       &sna->mode.shadow_cancel);
1824 
1825 	while (!list_is_empty(&sna->mode.shadow_crtc)) {
1826 		struct sna_crtc *crtc =
1827 			list_first_entry(&sna->mode.shadow_crtc, struct sna_crtc, shadow_link);
1828 		if (overlap(&crtc->base->bounds,
1829 			    &sna->mode.shadow_region.extents)) {
1830 			RegionRec region;
1831 			DrawableRec draw;
1832 
1833 			draw.width = crtc->base->mode.HDisplay;
1834 			draw.height = crtc->base->mode.VDisplay;
1835 			draw.depth = sna->front->drawable.depth;
1836 			draw.bitsPerPixel = sna->front->drawable.bitsPerPixel;
1837 
1838 			DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n",
1839 			     __FUNCTION__,
1840 			     crtc->base->bounds.x1,
1841 			     crtc->base->bounds.y1,
1842 			     crtc->base->bounds.x2,
1843 			     crtc->base->bounds.y2,
1844 			     crtc->client_bo->handle));
1845 
1846 			ret = sna->render.copy_boxes(sna, GXcopy,
1847 						     &draw, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
1848 						     &pixmap->drawable, bo, 0, 0,
1849 						     &crtc->base->bounds, 1,
1850 						     0);
1851 
1852 
1853 			region.extents = crtc->base->bounds;
1854 			region.data = NULL;
1855 			RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, &region);
1856 		}
1857 
1858 		crtc->client_bo->active_scanout--;
1859 		kgem_bo_destroy(&sna->kgem, crtc->client_bo);
1860 		crtc->client_bo = NULL;
1861 		list_del(&crtc->shadow_link);
1862 	}
1863 
1864 	if (RegionNotEmpty(&sna->mode.shadow_region)) {
1865 		DBG(("%s: copying existing GPU damage: %dx(%d, %d), (%d, %d)\n",
1866 		     __FUNCTION__, region_num_rects(&sna->mode.shadow_region),
1867 		     sna->mode.shadow_region.extents.x1,
1868 		     sna->mode.shadow_region.extents.y1,
1869 		     sna->mode.shadow_region.extents.x2,
1870 		     sna->mode.shadow_region.extents.y2));
1871 		if (!sna->render.copy_boxes(sna, GXcopy,
1872 					    &pixmap->drawable, priv->gpu_bo, 0, 0,
1873 					    &pixmap->drawable, bo, 0, 0,
1874 					    region_rects(&sna->mode.shadow_region),
1875 					    region_num_rects(&sna->mode.shadow_region),
1876 					    0))
1877 			ERR(("%s: copy failed\n", __FUNCTION__));
1878 	}
1879 
1880 	if (priv->cow)
1881 		sna_pixmap_undo_cow(sna, priv, 0);
1882 
1883 	sna_pixmap_unmap(pixmap, priv);
1884 
1885 	DBG(("%s: setting front pixmap to handle=%d\n", __FUNCTION__, bo->handle));
1886 	assert(sna->mode.shadow->active_scanout);
1887 	sna->mode.shadow->active_scanout--;
1888 	tmp = priv->gpu_bo;
1889 	priv->gpu_bo = bo;
1890 	if (bo != sna->mode.shadow)
1891 		kgem_bo_destroy(&sna->kgem, sna->mode.shadow);
1892 	sna->mode.shadow = tmp;
1893 	sna->mode.shadow->active_scanout++;
1894 	assert(sna->mode.shadow->active_scanout);
1895 
1896 	sna_dri2_pixmap_update_bo(sna, pixmap, bo);
1897 
1898 done:
1899 	RegionEmpty(&sna->mode.shadow_cancel);
1900 	RegionEmpty(&sna->mode.shadow_region);
1901 	sna->mode.shadow_dirty = false;
1902 
1903 	priv->move_to_gpu_data = NULL;
1904 	priv->move_to_gpu = NULL;
1905 
1906 	assert(sna->mode.shadow->active_scanout);
1907 	return ret;
1908 }
1909 
sna_pixmap_discard_shadow_damage(struct sna_pixmap * priv,const RegionRec * region)1910 bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv,
1911 				      const RegionRec *region)
1912 {
1913 	struct sna *sna;
1914 
1915 	if (priv->move_to_gpu != wait_for_shadow)
1916 		return false;
1917 
1918 	sna = priv->move_to_gpu_data;
1919 	if (region) {
1920 		DBG(("%s: discarding region %dx[(%d, %d), (%d, %d)] from damage %dx[(%d, %d], (%d, %d)]\n",
1921 		     __FUNCTION__,
1922 		     region_num_rects(region),
1923 		     region->extents.x1, region->extents.y1,
1924 		     region->extents.x2, region->extents.y2,
1925 		     region_num_rects(&sna->mode.shadow_region),
1926 		     sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1,
1927 		     sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2));
1928 
1929 		RegionSubtract(&sna->mode.shadow_region,
1930 			       &sna->mode.shadow_region,
1931 			       (RegionPtr)region);
1932 		RegionUnion(&sna->mode.shadow_cancel,
1933 			    &sna->mode.shadow_cancel,
1934 			    (RegionPtr)region);
1935 	} else {
1936 		DBG(("%s: discarding all damage %dx[(%d, %d], (%d, %d)]\n",
1937 		     __FUNCTION__,
1938 		     region_num_rects(&sna->mode.shadow_region),
1939 		     sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1,
1940 		     sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2));
1941 		RegionEmpty(&sna->mode.shadow_region);
1942 
1943 		RegionUninit(&sna->mode.shadow_cancel);
1944 		sna->mode.shadow_cancel.extents.x1 = 0;
1945 		sna->mode.shadow_cancel.extents.y1 = 0;
1946 		sna->mode.shadow_cancel.extents.x2 = sna->front->drawable.width;
1947 		sna->mode.shadow_cancel.extents.y2 = sna->front->drawable.height;
1948 		sna->mode.shadow_cancel.data = NULL;
1949 	}
1950 
1951 	return RegionNil(&sna->mode.shadow_region);
1952 }
1953 
sna_mode_damage(DamagePtr damage,RegionPtr region,void * closure)1954 static void sna_mode_damage(DamagePtr damage, RegionPtr region, void *closure)
1955 {
1956 	struct sna *sna = closure;
1957 
1958 	if (sna->mode.rr_active)
1959 		return;
1960 
1961 	/* Throw away the rectangles if the region grows too big */
1962 	region = DamageRegion(damage);
1963 	if (region->data) {
1964 		RegionRec dup;
1965 
1966 		dup = *region;
1967 		RegionUninit(&dup);
1968 
1969 		region->data = NULL;
1970 	}
1971 }
1972 
sna_mode_enable_shadow(struct sna * sna)1973 static bool sna_mode_enable_shadow(struct sna *sna)
1974 {
1975 	ScreenPtr screen = to_screen_from_sna(sna);
1976 
1977 	DBG(("%s\n", __FUNCTION__));
1978 	assert(sna->mode.shadow == NULL);
1979 	assert(sna->mode.shadow_damage == NULL);
1980 	assert(sna->mode.shadow_active == 0);
1981 	assert(!sna->mode.shadow_enabled);
1982 
1983 	sna->mode.shadow_damage = DamageCreate(sna_mode_damage, NULL,
1984 					       DamageReportRawRegion,
1985 					       TRUE, screen, sna);
1986 	if (!sna->mode.shadow_damage)
1987 		return false;
1988 
1989 	DamageRegister(&sna->front->drawable, sna->mode.shadow_damage);
1990 	sna->mode.shadow_enabled = true;
1991 	return true;
1992 }
1993 
sna_mode_disable_shadow(struct sna * sna)1994 static void sna_mode_disable_shadow(struct sna *sna)
1995 {
1996 	struct sna_pixmap *priv;
1997 
1998 	if (!sna->mode.shadow_damage) {
1999 		assert(!sna->mode.shadow_enabled);
2000 		return;
2001 	}
2002 
2003 	DBG(("%s\n", __FUNCTION__));
2004 
2005 	priv = sna_pixmap(sna->front);
2006 	if (priv->move_to_gpu == wait_for_shadow)
2007 		priv->move_to_gpu(sna, priv, 0);
2008 
2009 	DamageUnregister(&sna->front->drawable, sna->mode.shadow_damage);
2010 	DamageDestroy(sna->mode.shadow_damage);
2011 	sna->mode.shadow_damage = NULL;
2012 	sna->mode.shadow_enabled = false;
2013 
2014 	if (sna->mode.shadow) {
2015 		sna->mode.shadow->active_scanout--;
2016 		kgem_bo_destroy(&sna->kgem, sna->mode.shadow);
2017 		sna->mode.shadow = NULL;
2018 	}
2019 
2020 	assert(sna->mode.shadow_active == 0);
2021 	sna->mode.shadow_dirty = false;
2022 }
2023 
sna_crtc_slave_damage(DamagePtr damage,RegionPtr region,void * closure)2024 static void sna_crtc_slave_damage(DamagePtr damage, RegionPtr region, void *closure)
2025 {
2026 	struct sna_crtc *crtc = closure;
2027 	struct sna *sna = to_sna(crtc->base->scrn);
2028 	RegionPtr scr;
2029 
2030 	DBG(("%s: pushing damage [(%d, %d), (%d, %d) x %d] to CRTC [pipe=%d] (%d, %d)\n",
2031 	     __FUNCTION__,
2032 	     region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2,
2033 	     region_num_rects(region),
2034 	     __sna_crtc_pipe(crtc), crtc->base->x, crtc->base->y));
2035 
2036 	assert(crtc->slave_damage == damage);
2037 	assert(sna->mode.shadow_damage);
2038 
2039 	RegionTranslate(region, crtc->base->x, crtc->base->y);
2040 	scr = DamageRegion(sna->mode.shadow_damage);
2041 	RegionUnion(scr, scr, region);
2042 	RegionTranslate(region, -crtc->base->x, -crtc->base->y);
2043 }
2044 
sna_crtc_enable_shadow(struct sna * sna,struct sna_crtc * crtc)2045 static bool sna_crtc_enable_shadow(struct sna *sna, struct sna_crtc *crtc)
2046 {
2047 	if (crtc->shadow) {
2048 		assert(sna->mode.shadow_damage && sna->mode.shadow_active);
2049 		return true;
2050 	}
2051 
2052 	DBG(("%s: enabling for crtc %d\n", __FUNCTION__, __sna_crtc_id(crtc)));
2053 
2054 	if (!sna->mode.shadow_active) {
2055 		if (!sna_mode_enable_shadow(sna))
2056 			return false;
2057 		assert(sna->mode.shadow_damage);
2058 		assert(sna->mode.shadow == NULL);
2059 	}
2060 
2061 	if (crtc->slave_pixmap) {
2062 		assert(crtc->slave_damage == NULL);
2063 
2064 		DBG(("%s: enabling PRIME slave tracking on CRTC %d [pipe=%d], pixmap=%ld\n",
2065 		     __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->slave_pixmap->drawable.serialNumber));
2066 		crtc->slave_damage = DamageCreate(sna_crtc_slave_damage, NULL,
2067 						  DamageReportRawRegion, TRUE,
2068 						  to_screen_from_sna(sna),
2069 						  crtc);
2070 		if (crtc->slave_damage == NULL) {
2071 			if (!--sna->mode.shadow_active)
2072 				sna_mode_disable_shadow(sna);
2073 			return false;
2074 		}
2075 
2076 		DamageRegister(&crtc->slave_pixmap->drawable, crtc->slave_damage);
2077 	}
2078 
2079 	crtc->shadow = true;
2080 	sna->mode.shadow_active++;
2081 	return true;
2082 }
2083 
sna_crtc_disable_override(struct sna * sna,struct sna_crtc * crtc)2084 static void sna_crtc_disable_override(struct sna *sna, struct sna_crtc *crtc)
2085 {
2086 	if (crtc->client_bo == NULL)
2087 		return;
2088 
2089 	assert(crtc->client_bo->refcnt >= crtc->client_bo->active_scanout);
2090 	crtc->client_bo->active_scanout--;
2091 
2092 	if (!crtc->transform) {
2093 		DrawableRec tmp;
2094 
2095 		tmp.width = crtc->base->mode.HDisplay;
2096 		tmp.height = crtc->base->mode.VDisplay;
2097 		tmp.depth = sna->front->drawable.depth;
2098 		tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
2099 
2100 		sna->render.copy_boxes(sna, GXcopy,
2101 				       &tmp, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
2102 				       &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0,
2103 				       &crtc->base->bounds, 1, 0);
2104 		list_del(&crtc->shadow_link);
2105 	}
2106 	kgem_bo_destroy(&sna->kgem, crtc->client_bo);
2107 	crtc->client_bo = NULL;
2108 }
2109 
sna_crtc_disable_shadow(struct sna * sna,struct sna_crtc * crtc)2110 static void sna_crtc_disable_shadow(struct sna *sna, struct sna_crtc *crtc)
2111 {
2112 	crtc->fallback_shadow = false;
2113 	if (!crtc->shadow)
2114 		return;
2115 
2116 	DBG(("%s: disabling for crtc %d\n", __FUNCTION__, __sna_crtc_id(crtc)));
2117 	assert(sna->mode.shadow_active > 0);
2118 
2119 	if (crtc->slave_damage) {
2120 		assert(crtc->slave_pixmap);
2121 		DamageUnregister(&crtc->slave_pixmap->drawable, crtc->slave_damage);
2122 		DamageDestroy(crtc->slave_damage);
2123 		crtc->slave_damage = NULL;
2124 	}
2125 
2126 	sna_crtc_disable_override(sna, crtc);
2127 
2128 	if (!--sna->mode.shadow_active)
2129 		sna_mode_disable_shadow(sna);
2130 
2131 	crtc->shadow = false;
2132 }
2133 
2134 static void
__sna_crtc_disable(struct sna * sna,struct sna_crtc * sna_crtc)2135 __sna_crtc_disable(struct sna *sna, struct sna_crtc *sna_crtc)
2136 {
2137 	sna_crtc->mode_serial++;
2138 
2139 	sna_crtc_disable_cursor(sna, sna_crtc);
2140 	rotation_set(sna, &sna_crtc->primary, RR_Rotate_0);
2141 	sna_crtc_disable_shadow(sna, sna_crtc);
2142 
2143 	if (sna_crtc->bo) {
2144 		DBG(("%s: releasing handle=%d from scanout, active=%d\n",
2145 		     __FUNCTION__,sna_crtc->bo->handle, sna_crtc->bo->active_scanout-1));
2146 		assert(sna_crtc->public.flags & CRTC_ON);
2147 		assert(sna_crtc->bo->active_scanout);
2148 		assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout);
2149 		sna_crtc->bo->active_scanout--;
2150 		kgem_bo_destroy(&sna->kgem, sna_crtc->bo);
2151 		sna_crtc->bo = NULL;
2152 		sna_crtc->public.flags &= ~CRTC_ON;
2153 
2154 		if (sna->mode.hidden) {
2155 			sna->mode.hidden--;
2156 			assert(sna->mode.hidden);
2157 			assert(sna->mode.front_active == 0);
2158 		} else {
2159 			assert(sna->mode.front_active);
2160 			sna->mode.front_active--;
2161 		}
2162 		sna->mode.dirty = true;
2163 	}
2164 
2165 	if (sna_crtc->shadow_bo) {
2166 		kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo);
2167 		sna_crtc->shadow_bo = NULL;
2168 	}
2169 	if (sna_crtc->transform) {
2170 		assert(sna->mode.rr_active);
2171 		sna->mode.rr_active--;
2172 		sna_crtc->transform = false;
2173 	}
2174 
2175 	sna_crtc->cursor_transform = false;
2176 	sna_crtc->hwcursor = true;
2177 	assert(!sna_crtc->shadow);
2178 }
2179 
2180 static void
sna_crtc_disable(xf86CrtcPtr crtc,bool force)2181 sna_crtc_disable(xf86CrtcPtr crtc, bool force)
2182 {
2183 	struct sna *sna = to_sna(crtc->scrn);
2184 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
2185 	struct drm_mode_crtc arg;
2186 
2187 	if (sna_crtc == NULL)
2188 		return;
2189 
2190 	if (!force && sna_crtc->bo == NULL)
2191 		return;
2192 
2193 	DBG(("%s: disabling crtc [%d, pipe=%d], force?=%d\n", __FUNCTION__,
2194 	     __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), force));
2195 
2196 	sna_crtc_force_outputs_off(crtc);
2197 
2198 	memset(&arg, 0, sizeof(arg));
2199 	arg.crtc_id = __sna_crtc_id(sna_crtc);
2200 	(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
2201 
2202 	__sna_crtc_disable(sna, sna_crtc);
2203 }
2204 
update_flush_interval(struct sna * sna)2205 static void update_flush_interval(struct sna *sna)
2206 {
2207 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
2208 	int i, max_vrefresh = 0;
2209 
2210 	DBG(("%s: front_active=%d\n", __FUNCTION__, sna->mode.front_active));
2211 
2212 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
2213 		xf86CrtcPtr crtc = config->crtc[i];
2214 
2215 		assert(to_sna_crtc(crtc) != NULL);
2216 
2217 		if (!crtc->enabled) {
2218 			DBG(("%s: CRTC:%d (pipe %d) disabled\n",
2219 			     __FUNCTION__,i, sna_crtc_pipe(crtc)));
2220 			assert(to_sna_crtc(crtc)->bo == NULL);
2221 			continue;
2222 		}
2223 
2224 		if (to_sna_crtc(crtc)->bo == NULL) {
2225 			DBG(("%s: CRTC:%d (pipe %d) turned off\n",
2226 			     __FUNCTION__,i, sna_crtc_pipe(crtc)));
2227 			continue;
2228 		}
2229 
2230 		DBG(("%s: CRTC:%d (pipe %d) vrefresh=%f\n",
2231 		     __FUNCTION__, i, sna_crtc_pipe(crtc),
2232 		     xf86ModeVRefresh(&crtc->mode)));
2233 		max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(&crtc->mode));
2234 	}
2235 
2236 	if (max_vrefresh == 0) {
2237 		assert(sna->mode.front_active == 0);
2238 		sna->vblank_interval = 0;
2239 	} else
2240 		sna->vblank_interval = 1000 / max_vrefresh; /* Hz -> ms */
2241 
2242 	DBG(("max_vrefresh=%d, vblank_interval=%d ms\n",
2243 	       max_vrefresh, sna->vblank_interval));
2244 }
2245 
sna_create_bo_for_fbcon(struct sna * sna,const struct drm_mode_fb_cmd * fbcon)2246 static struct kgem_bo *sna_create_bo_for_fbcon(struct sna *sna,
2247 					       const struct drm_mode_fb_cmd *fbcon)
2248 {
2249 	struct drm_gem_flink flink;
2250 	struct kgem_bo *bo;
2251 	int ret;
2252 
2253 	/* Create a new reference for the fbcon so that we can track it
2254 	 * using a normal bo and so that when we call gem_close on it we
2255 	 * delete our reference and not fbcon's!
2256 	 */
2257 	VG_CLEAR(flink);
2258 	flink.handle = fbcon->handle;
2259 	ret = drmIoctl(sna->kgem.fd, DRM_IOCTL_GEM_FLINK, &flink);
2260 	if (ret)
2261 		return NULL;
2262 
2263 	bo = kgem_create_for_name(&sna->kgem, flink.name);
2264 	if (bo == NULL)
2265 		return NULL;
2266 
2267 	bo->pitch = fbcon->pitch;
2268 	return bo;
2269 }
2270 
2271 /* Copy the current framebuffer contents into the front-buffer for a seamless
2272  * transition from e.g. plymouth.
2273  */
sna_copy_fbcon(struct sna * sna)2274 void sna_copy_fbcon(struct sna *sna)
2275 {
2276 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
2277 	struct drm_mode_fb_cmd fbcon;
2278 	PixmapRec scratch;
2279 	struct sna_pixmap *priv;
2280 	struct kgem_bo *bo;
2281 	BoxRec box;
2282 	bool ok;
2283 	int sx, sy;
2284 	int dx, dy;
2285 	int i;
2286 
2287 	if (wedged(sna) || isGPU(sna->scrn))
2288 		return;
2289 
2290 	DBG(("%s\n", __FUNCTION__));
2291 	assert((sna->flags & SNA_IS_HOSTED) == 0);
2292 
2293 	priv = sna_pixmap_move_to_gpu(sna->front, MOVE_WRITE | __MOVE_SCANOUT);
2294 	if (priv == NULL)
2295 		return;
2296 
2297 	/* Scan the connectors for a framebuffer and assume that is the fbcon */
2298 	VG_CLEAR(fbcon);
2299 	fbcon.fb_id = 0;
2300 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
2301 		struct sna_crtc *crtc = to_sna_crtc(config->crtc[i]);
2302 		struct drm_mode_crtc mode;
2303 
2304 		assert(crtc != NULL);
2305 
2306 		VG_CLEAR(mode);
2307 		mode.crtc_id = __sna_crtc_id(crtc);
2308 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode))
2309 			continue;
2310 		if (!mode.fb_id)
2311 			continue;
2312 
2313 		fbcon.fb_id = mode.fb_id;
2314 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETFB, &fbcon)) {
2315 			fbcon.fb_id = 0;
2316 			continue;
2317 		}
2318 		break;
2319 	}
2320 	if (fbcon.fb_id == 0) {
2321 		DBG(("%s: no fbcon found\n", __FUNCTION__));
2322 		return;
2323 	}
2324 
2325 	if (fbcon.fb_id == fb_id(priv->gpu_bo)) {
2326 		DBG(("%s: fb already installed as scanout\n", __FUNCTION__));
2327 		return;
2328 	}
2329 
2330 	DBG(("%s: found fbcon, size=%dx%d, depth=%d, bpp=%d\n",
2331 	     __FUNCTION__, fbcon.width, fbcon.height, fbcon.depth, fbcon.bpp));
2332 
2333 	bo = sna_create_bo_for_fbcon(sna, &fbcon);
2334 	if (bo == NULL)
2335 		return;
2336 
2337 	DBG(("%s: fbcon handle=%d\n", __FUNCTION__, bo->handle));
2338 
2339 	scratch.drawable.width = fbcon.width;
2340 	scratch.drawable.height = fbcon.height;
2341 	scratch.drawable.depth = fbcon.depth;
2342 	scratch.drawable.bitsPerPixel = fbcon.bpp;
2343 	scratch.devPrivate.ptr = NULL;
2344 
2345 	box.x1 = box.y1 = 0;
2346 	box.x2 = min(fbcon.width, sna->front->drawable.width);
2347 	box.y2 = min(fbcon.height, sna->front->drawable.height);
2348 
2349 	sx = dx = 0;
2350 	if (box.x2 < (uint16_t)fbcon.width)
2351 		sx = (fbcon.width - box.x2) / 2;
2352 	if (box.x2 < sna->front->drawable.width)
2353 		dx = (sna->front->drawable.width - box.x2) / 2;
2354 
2355 	sy = dy = 0;
2356 	if (box.y2 < (uint16_t)fbcon.height)
2357 		sy = (fbcon.height - box.y2) / 2;
2358 	if (box.y2 < sna->front->drawable.height)
2359 		dy = (sna->front->drawable.height - box.y2) / 2;
2360 
2361 	ok = sna->render.copy_boxes(sna, GXcopy,
2362 				    &scratch.drawable, bo, sx, sy,
2363 				    &sna->front->drawable, priv->gpu_bo, dx, dy,
2364 				    &box, 1, 0);
2365 	if (!DAMAGE_IS_ALL(priv->gpu_damage))
2366 		sna_damage_add_box(&priv->gpu_damage, &box);
2367 
2368 	kgem_bo_destroy(&sna->kgem, bo);
2369 
2370 #if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(10, 0)
2371 	to_screen_from_sna(sna)->canDoBGNoneRoot = ok;
2372 #endif
2373 }
2374 
use_shadow(struct sna * sna,xf86CrtcPtr crtc)2375 static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc)
2376 {
2377 	RRTransformPtr transform;
2378 	PictTransform crtc_to_fb;
2379 	struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc;
2380 	unsigned pitch_limit;
2381 	BoxRec b;
2382 
2383 	assert(sna->scrn->virtualX && sna->scrn->virtualY);
2384 
2385 	if (sna->flags & SNA_FORCE_SHADOW) {
2386 		DBG(("%s: forcing shadow\n", __FUNCTION__));
2387 		return true;
2388 	}
2389 
2390 	if (to_sna_crtc(crtc)->fallback_shadow) {
2391 		DBG(("%s: fallback shadow\n", __FUNCTION__));
2392 		return true;
2393 	}
2394 
2395 	if (sna->flags & SNA_TEAR_FREE && to_sna_crtc(crtc)->slave_pixmap) {
2396 		DBG(("%s: TearFree shadow required\n", __FUNCTION__));
2397 		return true;
2398 	}
2399 
2400 	if (sna->scrn->virtualX > sna->mode.max_crtc_width ||
2401 	    sna->scrn->virtualY > sna->mode.max_crtc_height) {
2402 		DBG(("%s: framebuffer too large (%dx%d) > (%dx%d)\n",
2403 		    __FUNCTION__,
2404 		    sna->scrn->virtualX, sna->scrn->virtualY,
2405 		    sna->mode.max_crtc_width, sna->mode.max_crtc_height));
2406 		return true;
2407 	}
2408 
2409 	if (!isGPU(sna->scrn)) {
2410 		struct sna_pixmap *priv;
2411 
2412 		priv = sna_pixmap_force_to_gpu(sna->front, MOVE_READ | __MOVE_SCANOUT);
2413 		if (priv == NULL)
2414 			return true; /* maybe we can create a bo for the scanout? */
2415 
2416 		if (sna->kgem.gen == 071)
2417 			pitch_limit = priv->gpu_bo->tiling ? 16 * 1024 : 32 * 1024;
2418 		else if ((sna->kgem.gen >> 3) > 4)
2419 			pitch_limit = 32 * 1024;
2420 		else if ((sna->kgem.gen >> 3) == 4)
2421 			pitch_limit = priv->gpu_bo->tiling ? 16 * 1024 : 32 * 1024;
2422 		else if ((sna->kgem.gen >> 3) == 3)
2423 			pitch_limit = priv->gpu_bo->tiling ? 8 * 1024 : 16 * 1024;
2424 		else
2425 			pitch_limit = 8 * 1024;
2426 		DBG(("%s: gpu bo handle=%d tiling=%d pitch=%d, limit=%d\n", __FUNCTION__, priv->gpu_bo->handle, priv->gpu_bo->tiling, priv->gpu_bo->pitch, pitch_limit));
2427 		if (priv->gpu_bo->pitch > pitch_limit)
2428 			return true;
2429 
2430 		if (priv->gpu_bo->tiling && sna->flags & SNA_LINEAR_FB) {
2431 			DBG(("%s: gpu bo is tiled, need linear, forcing shadow\n", __FUNCTION__));
2432 			return true;
2433 		}
2434 	}
2435 
2436 	transform = NULL;
2437 	if (crtc->transformPresent)
2438 		transform = &crtc->transform;
2439 	if (RRTransformCompute(crtc->x, crtc->y,
2440 			       crtc->mode.HDisplay, crtc->mode.VDisplay,
2441 			       crtc->rotation, transform,
2442 			       &crtc_to_fb,
2443 			       &f_crtc_to_fb,
2444 			       &f_fb_to_crtc)) {
2445 		bool needs_transform = true;
2446 		unsigned rotation = rotation_reduce(&to_sna_crtc(crtc)->primary, crtc->rotation);
2447 		DBG(("%s: natively supported rotation? rotation=%x & supported=%x == %d\n",
2448 		     __FUNCTION__, rotation, to_sna_crtc(crtc)->primary.rotation.supported,
2449 		     rotation == (rotation & to_sna_crtc(crtc)->primary.rotation.supported)));
2450 		if ((to_sna_crtc(crtc)->primary.rotation.supported & rotation) == rotation)
2451 			needs_transform = RRTransformCompute(crtc->x, crtc->y,
2452 							     crtc->mode.HDisplay, crtc->mode.VDisplay,
2453 							     RR_Rotate_0, transform,
2454 							     NULL, NULL, NULL);
2455 		if (needs_transform) {
2456 			DBG(("%s: RandR transform present\n", __FUNCTION__));
2457 			return true;
2458 		}
2459 	}
2460 
2461 	/* And finally check that it is entirely visible */
2462 	b.x1 = b.y1 = 0;
2463 	b.x2 = crtc->mode.HDisplay;
2464 	b.y2 = crtc->mode.VDisplay;
2465 	pixman_f_transform_bounds(&f_crtc_to_fb, &b);
2466 	DBG(("%s? bounds (%d, %d), (%d, %d), framebufer %dx%d\n",
2467 	     __FUNCTION__, b.x1, b.y1, b.x2, b.y2,
2468 		 sna->scrn->virtualX, sna->scrn->virtualY));
2469 
2470 	if  (b.x1 < 0 || b.y1 < 0 ||
2471 	     b.x2 > sna->scrn->virtualX ||
2472 	     b.y2 > sna->scrn->virtualY) {
2473 		DBG(("%s: scanout is partly outside the framebuffer\n",
2474 		     __FUNCTION__));
2475 		return true;
2476 	}
2477 
2478 	return false;
2479 }
2480 
set_shadow(struct sna * sna,RegionPtr region)2481 static void set_shadow(struct sna *sna, RegionPtr region)
2482 {
2483 	struct sna_pixmap *priv = sna_pixmap(sna->front);
2484 
2485 	assert(priv->gpu_bo);
2486 	assert(sna->mode.shadow);
2487 	assert(sna->mode.shadow->active_scanout);
2488 
2489 	DBG(("%s: waiting for region %dx[(%d, %d), (%d, %d)], front handle=%d, shadow handle=%d\n",
2490 	     __FUNCTION__,
2491 	     region_num_rects(region),
2492 	     region->extents.x1, region->extents.y1,
2493 	     region->extents.x2, region->extents.y2,
2494 	     priv->gpu_bo->handle, sna->mode.shadow->handle));
2495 
2496 	assert(priv->pinned & PIN_SCANOUT);
2497 	assert((priv->pinned & PIN_PRIME) == 0);
2498 	assert(sna->mode.shadow != priv->gpu_bo);
2499 
2500 	RegionCopy(&sna->mode.shadow_region, region);
2501 
2502 	priv->move_to_gpu = wait_for_shadow;
2503 	priv->move_to_gpu_data = sna;
2504 }
2505 
2506 static struct kgem_bo *
get_scanout_bo(struct sna * sna,PixmapPtr pixmap)2507 get_scanout_bo(struct sna *sna, PixmapPtr pixmap)
2508 {
2509 	struct sna_pixmap *priv;
2510 
2511 	priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | __MOVE_SCANOUT);
2512 	if (!priv)
2513 		return NULL;
2514 
2515 	if (priv->gpu_bo->pitch & 63) {
2516 		struct kgem_bo *tmp;
2517 		BoxRec b;
2518 
2519 		DBG(("%s: converting to scanout bo due to bad pitch [%d]\n",
2520 		     __FUNCTION__, priv->gpu_bo->pitch));
2521 
2522 		if (priv->pinned) {
2523 			DBG(("%s: failed as the Pixmap is already pinned [%x]\n",
2524 			     __FUNCTION__, priv->pinned));
2525 			return NULL;
2526 		}
2527 
2528 		tmp = kgem_create_2d(&sna->kgem,
2529 				     pixmap->drawable.width,
2530 				     pixmap->drawable.height,
2531 				     sna->scrn->bitsPerPixel,
2532 				     priv->gpu_bo->tiling,
2533 				     CREATE_EXACT | CREATE_SCANOUT);
2534 		if (tmp == NULL) {
2535 			DBG(("%s: allocation failed\n", __FUNCTION__));
2536 			return NULL;
2537 		}
2538 
2539 		b.x1 = 0;
2540 		b.y1 = 0;
2541 		b.x2 = pixmap->drawable.width;
2542 		b.y2 = pixmap->drawable.height;
2543 
2544 		if (sna->render.copy_boxes(sna, GXcopy,
2545 					   &pixmap->drawable, priv->gpu_bo, 0, 0,
2546 					   &pixmap->drawable, tmp, 0, 0,
2547 					   &b, 1, COPY_LAST)) {
2548 			DBG(("%s: copy failed\n", __FUNCTION__));
2549 			kgem_bo_destroy(&sna->kgem, tmp);
2550 			return NULL;
2551 		}
2552 
2553 		kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
2554 		priv->gpu_bo = tmp;
2555 	}
2556 
2557 	priv->pinned |= PIN_SCANOUT;
2558 	return priv->gpu_bo;
2559 }
2560 
shadow_clear(struct sna * sna,PixmapPtr front,struct kgem_bo * bo,xf86CrtcPtr crtc)2561 static void shadow_clear(struct sna *sna,
2562 			 PixmapPtr front, struct kgem_bo *bo,
2563 			 xf86CrtcPtr crtc)
2564 {
2565 	bool ok = false;
2566 	if (!wedged(sna))
2567 		ok = sna->render.fill_one(sna, front, bo, 0,
2568 					  0, 0, crtc->mode.HDisplay, crtc->mode.VDisplay,
2569 					  GXclear);
2570 	if (!ok) {
2571 		void *ptr = kgem_bo_map__gtt(&sna->kgem, bo);
2572 		if (ptr)
2573 			memset(ptr, 0, bo->pitch * crtc->mode.VDisplay);
2574 	}
2575 	sna->mode.shadow_dirty = true;
2576 }
2577 
rr_active(xf86CrtcPtr crtc)2578 static bool rr_active(xf86CrtcPtr crtc)
2579 {
2580 	return crtc->transformPresent || crtc->rotation != RR_Rotate_0;
2581 }
2582 
sna_crtc_attach(xf86CrtcPtr crtc)2583 static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
2584 {
2585 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
2586 	ScrnInfoPtr scrn = crtc->scrn;
2587 	struct sna *sna = to_sna(scrn);
2588 	struct kgem_bo *bo;
2589 
2590 	if (sna_crtc->transform) {
2591 		assert(sna->mode.rr_active);
2592 		sna_crtc->transform = false;
2593 		sna->mode.rr_active--;
2594 	}
2595 	sna_crtc->rotation = RR_Rotate_0;
2596 
2597 	if (sna_crtc->cache_bo) {
2598 		kgem_bo_destroy(&sna->kgem, sna_crtc->cache_bo);
2599 		sna_crtc->cache_bo = NULL;
2600 	}
2601 
2602 	if (use_shadow(sna, crtc)) {
2603 		PixmapPtr front;
2604 		unsigned long tiled_limit;
2605 		int tiling;
2606 
2607 force_shadow:
2608 		if (!sna_crtc_enable_shadow(sna, sna_crtc)) {
2609 			DBG(("%s: failed to enable crtc shadow\n", __FUNCTION__));
2610 			return NULL;
2611 		}
2612 
2613 		DBG(("%s: attaching to per-crtc pixmap %dx%d\n",
2614 		     __FUNCTION__, crtc->mode.HDisplay, crtc->mode.VDisplay));
2615 
2616 		bo = sna_crtc->shadow_bo;
2617 		if (bo) {
2618 			if (sna_crtc->shadow_bo_width == crtc->mode.HDisplay &&
2619 			    sna_crtc->shadow_bo_height == crtc->mode.VDisplay) {
2620 				DBG(("%s: reusing current shadow bo handle=%d\n",
2621 				     __FUNCTION__, bo->handle));
2622 				goto out_shadow;
2623 			}
2624 
2625 			kgem_bo_destroy(&sna->kgem, bo);
2626 			sna_crtc->shadow_bo = NULL;
2627 		}
2628 
2629 		tiling = I915_TILING_X;
2630 		if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270) &&
2631 		    sna->kgem.can_scanout_y)
2632 			tiling = I915_TILING_Y;
2633 
2634 		if (sna->kgem.gen == 071)
2635 			tiled_limit = 16 * 1024 * 8;
2636 		else if ((sna->kgem.gen >> 3) > 4)
2637 			tiled_limit = 32 * 1024 * 8;
2638 		else if ((sna->kgem.gen >> 3) == 4)
2639 			tiled_limit = 16 * 1024 * 8;
2640 		else
2641 			tiled_limit = 8 * 1024 * 8;
2642 		if ((unsigned long)crtc->mode.HDisplay * scrn->bitsPerPixel > tiled_limit)
2643 			tiling = I915_TILING_NONE;
2644 		if (sna->flags & SNA_LINEAR_FB)
2645 			tiling = I915_TILING_NONE;
2646 
2647 		bo = kgem_create_2d(&sna->kgem,
2648 				    crtc->mode.HDisplay, crtc->mode.VDisplay,
2649 				    scrn->bitsPerPixel,
2650 				    tiling, CREATE_SCANOUT);
2651 		if (bo == NULL) {
2652 			DBG(("%s: failed to allocate crtc scanout\n", __FUNCTION__));
2653 			return NULL;
2654 		}
2655 
2656 		if (!get_fb(sna, bo, crtc->mode.HDisplay, crtc->mode.VDisplay)) {
2657 			DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
2658 			kgem_bo_destroy(&sna->kgem, bo);
2659 			return NULL;
2660 		}
2661 
2662 		front = sna_crtc->slave_pixmap ?: sna->front;
2663 		if (__sna_pixmap_get_bo(front) && !rr_active(crtc)) {
2664 			BoxRec b;
2665 
2666 			b.x1 = crtc->x;
2667 			b.y1 = crtc->y;
2668 			b.x2 = crtc->x + crtc->mode.HDisplay;
2669 			b.y2 = crtc->y + crtc->mode.VDisplay;
2670 
2671 			if (b.x1 < 0)
2672 				b.x1 = 0;
2673 			if (b.y1 < 0)
2674 				b.y1 = 0;
2675 			if (b.x2 > scrn->virtualX)
2676 				b.x2 = scrn->virtualX;
2677 			if (b.y2 > scrn->virtualY)
2678 				b.y2 = scrn->virtualY;
2679 			if (b.x2 - b.x1 < crtc->mode.HDisplay ||
2680 			    b.y2 - b.y1 < crtc->mode.VDisplay)
2681 				shadow_clear(sna, front, bo, crtc);
2682 
2683 			if (b.y2 > b.y1 && b.x2 > b.x1) {
2684 				DrawableRec tmp;
2685 
2686 				DBG(("%s: copying onto shadow CRTC: (%d, %d)x(%d, %d) [fb=%dx%d], handle=%d\n",
2687 				     __FUNCTION__,
2688 				     b.x1, b.y1,
2689 				     b.x2-b.x1, b.y2-b.y1,
2690 				     scrn->virtualX, scrn->virtualY,
2691 				     bo->handle));
2692 
2693 				tmp.width = crtc->mode.HDisplay;
2694 				tmp.height = crtc->mode.VDisplay;
2695 				tmp.depth = front->drawable.depth;
2696 				tmp.bitsPerPixel = front->drawable.bitsPerPixel;
2697 
2698 				if (!sna->render.copy_boxes(sna, GXcopy,
2699 							     &front->drawable, __sna_pixmap_get_bo(front), 0, 0,
2700 							     &tmp, bo, -crtc->x, -crtc->y,
2701 							     &b, 1, COPY_LAST))
2702 					shadow_clear(sna, front, bo, crtc);
2703 			}
2704 		} else
2705 			shadow_clear(sna, front, bo, crtc);
2706 
2707 		sna_crtc->shadow_bo_width = crtc->mode.HDisplay;
2708 		sna_crtc->shadow_bo_height = crtc->mode.VDisplay;
2709 		sna_crtc->shadow_bo = bo;
2710 out_shadow:
2711 		sna_crtc->transform = true;
2712 		sna->mode.rr_active++;
2713 		return kgem_bo_reference(bo);
2714 	} else {
2715 		if (sna_crtc->shadow_bo) {
2716 			kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo);
2717 			sna_crtc->shadow_bo = NULL;
2718 		}
2719 
2720 		if (sna_crtc->slave_pixmap) {
2721 			DBG(("%s: attaching to scanout pixmap\n", __FUNCTION__));
2722 			bo = get_scanout_bo(sna, sna_crtc->slave_pixmap);
2723 			if (bo == NULL) {
2724 				DBG(("%s: failed to pin crtc scanout\n", __FUNCTION__));
2725 				sna_crtc->fallback_shadow = true;
2726 				goto force_shadow;
2727 			}
2728 
2729 			if (!get_fb(sna, bo,
2730 				    sna_crtc->slave_pixmap->drawable.width,
2731 				    sna_crtc->slave_pixmap->drawable.height)) {
2732 				DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
2733 				sna_crtc->fallback_shadow = true;
2734 				goto force_shadow;
2735 			}
2736 		} else {
2737 			DBG(("%s: attaching to framebuffer\n", __FUNCTION__));
2738 			bo = get_scanout_bo(sna, sna->front);
2739 			if (bo == NULL) {
2740 				DBG(("%s: failed to pin framebuffer\n", __FUNCTION__));
2741 				sna_crtc->fallback_shadow = true;
2742 				goto force_shadow;
2743 			}
2744 
2745 			if (!get_fb(sna, bo, scrn->virtualX, scrn->virtualY)) {
2746 				DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
2747 				sna_crtc->fallback_shadow = true;
2748 				goto force_shadow;
2749 			}
2750 		}
2751 
2752 		if (sna->flags & SNA_TEAR_FREE) {
2753 			RegionRec region;
2754 
2755 			assert(sna_crtc->slave_pixmap == NULL);
2756 
2757 			DBG(("%s: enabling TearFree shadow\n", __FUNCTION__));
2758 			region.extents.x1 = 0;
2759 			region.extents.y1 = 0;
2760 			region.extents.x2 = sna->scrn->virtualX;
2761 			region.extents.y2 = sna->scrn->virtualY;
2762 			region.data = NULL;
2763 
2764 			if (!sna_crtc_enable_shadow(sna, sna_crtc)) {
2765 				DBG(("%s: failed to enable crtc shadow\n", __FUNCTION__));
2766 				return NULL;
2767 			}
2768 
2769 			if (sna->mode.shadow == NULL) {
2770 				struct kgem_bo *shadow;
2771 
2772 				DBG(("%s: creating TearFree shadow bo\n", __FUNCTION__));
2773 				shadow = kgem_create_2d(&sna->kgem,
2774 							region.extents.x2,
2775 							region.extents.y2,
2776 							scrn->bitsPerPixel,
2777 							kgem_choose_tiling(&sna->kgem,
2778 									   I915_TILING_X,
2779 									   region.extents.x2,
2780 									   region.extents.y2,
2781 									   sna->scrn->bitsPerPixel),
2782 							CREATE_SCANOUT);
2783 				if (shadow == NULL) {
2784 					DBG(("%s: failed to allocate TearFree shadow bo\n", __FUNCTION__));
2785 					sna_crtc->fallback_shadow = true;
2786 					goto force_shadow;
2787 				}
2788 
2789 				if (!get_fb(sna, shadow,
2790 					    region.extents.x2,
2791 					    region.extents.y2)) {
2792 					DBG(("%s: failed to bind fb for TearFeee shadow\n", __FUNCTION__));
2793 					kgem_bo_destroy(&sna->kgem, shadow);
2794 					sna_crtc->fallback_shadow = true;
2795 					goto force_shadow;
2796 				}
2797 
2798 				assert(__sna_pixmap_get_bo(sna->front) == NULL ||
2799 				       __sna_pixmap_get_bo(sna->front)->pitch == shadow->pitch);
2800 				sna->mode.shadow = shadow;
2801 				sna->mode.shadow->active_scanout++;
2802 			}
2803 			set_shadow(sna, &region);
2804 
2805 			sna_crtc_disable_override(sna, sna_crtc);
2806 		} else
2807 			sna_crtc_disable_shadow(sna, sna_crtc);
2808 
2809 		sna_crtc->rotation = rotation_reduce(&sna_crtc->primary, crtc->rotation);
2810 		assert(sna_crtc->primary.rotation.supported & sna_crtc->rotation);
2811 		return kgem_bo_reference(bo);
2812 	}
2813 }
2814 
2815 #define SCALING_EPSILON (1./256)
2816 
2817 static bool
is_affine(const struct pixman_f_transform * t)2818 is_affine(const struct pixman_f_transform *t)
2819 {
2820 	return (fabs(t->m[2][0]) < SCALING_EPSILON &&
2821 		fabs(t->m[2][1]) < SCALING_EPSILON);
2822 }
2823 
determinant(const struct pixman_f_transform * t)2824 static double determinant(const struct pixman_f_transform *t)
2825 {
2826 	return t->m[0][0]*t->m[1][1] - t->m[1][0]*t->m[0][1];
2827 }
2828 
2829 static bool
affine_is_pixel_exact(const struct pixman_f_transform * t)2830 affine_is_pixel_exact(const struct pixman_f_transform *t)
2831 {
2832 	double det = t->m[2][2] * determinant(t);
2833 	if (fabs (det * det - 1.0) < SCALING_EPSILON) {
2834 		if (fabs(t->m[0][1]) < SCALING_EPSILON &&
2835 		    fabs(t->m[1][0]) < SCALING_EPSILON)
2836 			return true;
2837 
2838 		if (fabs(t->m[0][0]) < SCALING_EPSILON &&
2839 		    fabs(t->m[1][1]) < SCALING_EPSILON)
2840 			return true;
2841 	}
2842 
2843 	return false;
2844 }
2845 
sna_crtc_randr(xf86CrtcPtr crtc)2846 static void sna_crtc_randr(xf86CrtcPtr crtc)
2847 {
2848 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
2849 	struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc;
2850 	PictTransform crtc_to_fb;
2851 	PictFilterPtr filter;
2852 	xFixed *params;
2853 	int nparams;
2854 	RRTransformPtr transform;
2855 	int needs_transform;
2856 
2857 	transform = NULL;
2858 	if (crtc->transformPresent)
2859 		transform = &crtc->transform;
2860 
2861 	needs_transform =
2862 		RRTransformCompute(crtc->x, crtc->y,
2863 				   crtc->mode.HDisplay, crtc->mode.VDisplay,
2864 				   crtc->rotation, transform,
2865 				   &crtc_to_fb,
2866 				   &f_crtc_to_fb,
2867 				   &f_fb_to_crtc);
2868 
2869 	filter = NULL;
2870 	params = NULL;
2871 	nparams = 0;
2872 	if (sna_crtc->transform) {
2873 #ifdef RANDR_12_INTERFACE
2874 		if (transform) {
2875 			if (transform->nparams) {
2876 				params = malloc(transform->nparams * sizeof(xFixed));
2877 				if (params) {
2878 					memcpy(params, transform->params,
2879 					       transform->nparams * sizeof(xFixed));
2880 					nparams = transform->nparams;
2881 					filter = transform->filter;
2882 				}
2883 			} else
2884 				filter = transform->filter;
2885 		}
2886 #endif
2887 		crtc->transform_in_use = needs_transform;
2888 	} else
2889 		crtc->transform_in_use = sna_crtc->rotation != RR_Rotate_0;
2890 
2891 	/* Recompute the cursor after a potential change in transform */
2892 	if (sna_crtc->cursor) {
2893 		assert(sna_crtc->cursor->ref > 0);
2894 		sna_crtc->cursor->ref--;
2895 		sna_crtc->cursor = NULL;
2896 	}
2897 
2898 	if (needs_transform) {
2899 		sna_crtc->hwcursor = is_affine(&f_fb_to_crtc);
2900 		sna_crtc->cursor_transform =
2901 			sna_crtc->hwcursor &&
2902 			!affine_is_pixel_exact(&f_fb_to_crtc);
2903 	} else {
2904 		sna_crtc->hwcursor = true;
2905 		sna_crtc->cursor_transform = false;
2906 	}
2907 	DBG(("%s: hwcursor?=%d, cursor_transform?=%d\n",
2908 	     __FUNCTION__, sna_crtc->hwcursor, sna_crtc->cursor_transform));
2909 
2910 	crtc->crtc_to_framebuffer = crtc_to_fb;
2911 	crtc->f_crtc_to_framebuffer = f_crtc_to_fb;
2912 	crtc->f_framebuffer_to_crtc = f_fb_to_crtc;
2913 
2914 	free(crtc->params);
2915 	crtc->params  = params;
2916 	crtc->nparams = nparams;
2917 
2918 	crtc->filter = filter;
2919 	if (filter) {
2920 		crtc->filter_width  = filter->width;
2921 		crtc->filter_height = filter->height;
2922 	} else {
2923 		crtc->filter_width  = 0;
2924 		crtc->filter_height = 0;
2925 	}
2926 
2927 	crtc->bounds.x1 = 0;
2928 	crtc->bounds.x2 = crtc->mode.HDisplay;
2929 	crtc->bounds.y1 = 0;
2930 	crtc->bounds.y2 = crtc->mode.VDisplay;
2931 	pixman_f_transform_bounds(&f_crtc_to_fb, &crtc->bounds);
2932 
2933 	DBG(("%s: transform? %d, bounds (%d, %d), (%d, %d)\n",
2934 	     __FUNCTION__, crtc->transform_in_use,
2935 	     crtc->bounds.x1, crtc->bounds.y1,
2936 	     crtc->bounds.x2, crtc->bounds.y2));
2937 }
2938 
2939 static void
sna_crtc_damage(xf86CrtcPtr crtc)2940 sna_crtc_damage(xf86CrtcPtr crtc)
2941 {
2942 	ScreenPtr screen = xf86ScrnToScreen(crtc->scrn);
2943 	struct sna *sna = to_sna(crtc->scrn);
2944 	RegionRec region, *damage;
2945 
2946 	region.extents = crtc->bounds;
2947 	region.data = NULL;
2948 
2949 	if (region.extents.x1 < 0)
2950 		region.extents.x1 = 0;
2951 	if (region.extents.y1 < 0)
2952 		region.extents.y1 = 0;
2953 	if (region.extents.x2 > screen->width)
2954 		region.extents.x2 = screen->width;
2955 	if (region.extents.y2 > screen->height)
2956 		region.extents.y2 = screen->height;
2957 
2958 	if (region.extents.x2 <= region.extents.x1 ||
2959 	    region.extents.y2 <= region.extents.y1) {
2960 		DBG(("%s: crtc not damaged, all-clipped\n", __FUNCTION__));
2961 		return;
2962 	}
2963 
2964 	DBG(("%s: marking crtc %d as completely damaged (%d, %d), (%d, %d)\n",
2965 	     __FUNCTION__, sna_crtc_id(crtc),
2966 	     region.extents.x1, region.extents.y1,
2967 	     region.extents.x2, region.extents.y2));
2968 
2969 	assert(sna->mode.shadow_damage && sna->mode.shadow_active);
2970 	damage = DamageRegion(sna->mode.shadow_damage);
2971 	RegionUnion(damage, damage, &region);
2972 	to_sna_crtc(crtc)->crtc_damage = region;
2973 
2974 	DBG(("%s: damage now %dx[(%d, %d), (%d, %d)]\n",
2975 	     __FUNCTION__,
2976 	     region_num_rects(damage),
2977 	     damage->extents.x1, damage->extents.y1,
2978 	     damage->extents.x2, damage->extents.y2));
2979 }
2980 
outputs_for_crtc(xf86CrtcPtr crtc,char * outputs,int max)2981 static char *outputs_for_crtc(xf86CrtcPtr crtc, char *outputs, int max)
2982 {
2983 	struct sna *sna = to_sna(crtc->scrn);
2984 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
2985 	int len, i;
2986 
2987 	for (i = len = 0; i < sna->mode.num_real_output; i++) {
2988 		xf86OutputPtr output = config->output[i];
2989 
2990 		if (output->crtc != crtc)
2991 			continue;
2992 
2993 		len += snprintf(outputs+len, max-len, "%s, ", output->name);
2994 	}
2995 	assert(len >= 2);
2996 	outputs[len-2] = '\0';
2997 
2998 	return outputs;
2999 }
3000 
rotation_to_str(Rotation rotation)3001 static const char *rotation_to_str(Rotation rotation)
3002 {
3003 	switch (rotation & RR_Rotate_All) {
3004 	case 0:
3005 	case RR_Rotate_0: return "normal";
3006 	case RR_Rotate_90: return "left";
3007 	case RR_Rotate_180: return "inverted";
3008 	case RR_Rotate_270: return "right";
3009 	default: return "unknown";
3010 	}
3011 }
3012 
reflection_to_str(Rotation rotation)3013 static const char *reflection_to_str(Rotation rotation)
3014 {
3015 	switch (rotation & RR_Reflect_All) {
3016 	case 0: return "none";
3017 	case RR_Reflect_X: return "X axis";
3018 	case RR_Reflect_Y: return "Y axis";
3019 	case RR_Reflect_X | RR_Reflect_Y: return "X and Y axes";
3020 	default: return "invalid";
3021 	}
3022 }
3023 
reprobe_connectors(xf86CrtcPtr crtc)3024 static void reprobe_connectors(xf86CrtcPtr crtc)
3025 {
3026 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
3027 	struct sna *sna = to_sna(crtc->scrn);
3028 	int i;
3029 
3030 	for (i = 0; i < sna->mode.num_real_output; i++) {
3031 		xf86OutputPtr output = config->output[i];
3032 		if (output->crtc == crtc)
3033 			to_sna_output(output)->reprobe = true;
3034 	}
3035 
3036 	sna_mode_discover(sna, true);
3037 }
3038 
3039 static Bool
__sna_crtc_set_mode(xf86CrtcPtr crtc)3040 __sna_crtc_set_mode(xf86CrtcPtr crtc)
3041 {
3042 	struct sna *sna = to_sna(crtc->scrn);
3043 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
3044 	struct kgem_bo *saved_bo, *bo;
3045 	uint32_t saved_offset;
3046 	bool saved_transform;
3047 	bool saved_hwcursor;
3048 	bool saved_cursor_transform;
3049 	int ret;
3050 
3051 	DBG(("%s: CRTC=%d, pipe=%d, hidden?=%d\n", __FUNCTION__,
3052 	     __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), sna->mode.hidden));
3053 	if (sna->mode.hidden)
3054 		return TRUE;
3055 
3056 	saved_bo = sna_crtc->bo;
3057 	saved_transform = sna_crtc->transform;
3058 	saved_cursor_transform = sna_crtc->cursor_transform;
3059 	saved_hwcursor = sna_crtc->hwcursor;
3060 	saved_offset = sna_crtc->offset;
3061 
3062 	sna_crtc->fallback_shadow = false;
3063 retry: /* Attach per-crtc pixmap or direct */
3064 	bo = sna_crtc_attach(crtc);
3065 	if (bo == NULL) {
3066 		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
3067 			   "unable to attach scanout\n");
3068 		goto error;
3069 	}
3070 
3071 	/* Prevent recursion when enabling outputs during execbuffer */
3072 	if (bo->exec && RQ(bo->rq)->bo == NULL) {
3073 		_kgem_submit(&sna->kgem);
3074 		__kgem_bo_clear_dirty(bo);
3075 	}
3076 
3077 	sna_crtc->bo = bo;
3078 	ret = sna_crtc_apply(crtc);
3079 	if (ret) {
3080 		kgem_bo_destroy(&sna->kgem, bo);
3081 
3082 		if (!sna_crtc->fallback_shadow) {
3083 			sna_crtc->fallback_shadow = true;
3084 			goto retry;
3085 		}
3086 
3087 		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
3088 			   "failed to set mode: %s [%d]\n", strerror(ret), ret);
3089 		goto error;
3090 	}
3091 
3092 	sna_crtc->public.flags |= CRTC_ON;
3093 	bo->active_scanout++;
3094 	DBG(("%s: marking handle=%d as active=%d (removing %d from scanout, active=%d)\n",
3095 	     __FUNCTION__, bo->handle, bo->active_scanout,
3096 	     saved_bo ? saved_bo->handle : 0, saved_bo ? saved_bo->active_scanout - 1: -1));
3097 	if (saved_bo) {
3098 		assert(saved_bo->active_scanout);
3099 		assert(saved_bo->refcnt >= saved_bo->active_scanout);
3100 		saved_bo->active_scanout--;
3101 		kgem_bo_destroy(&sna->kgem, saved_bo);
3102 	}
3103 
3104 	sna_crtc_randr(crtc);
3105 	if (sna_crtc->transform)
3106 		sna_crtc_damage(crtc);
3107 	if (sna_crtc->cursor &&  /* Reload cursor if RandR maybe changed */
3108 	    (!sna_crtc->hwcursor ||
3109 	     saved_cursor_transform || sna_crtc->cursor_transform ||
3110 	     sna_crtc->cursor->rotation != crtc->rotation))
3111 		sna_crtc_disable_cursor(sna, sna_crtc);
3112 
3113 	assert(!sna->mode.hidden);
3114 	sna->mode.front_active += saved_bo == NULL;
3115 	sna->mode.dirty = true;
3116 	DBG(("%s: handle=%d, scanout_active=%d, front_active=%d\n",
3117 	     __FUNCTION__, bo->handle, bo->active_scanout, sna->mode.front_active));
3118 
3119 	return TRUE;
3120 
3121 error:
3122 	sna_crtc->offset = saved_offset;
3123 	if (sna_crtc->transform) {
3124 		assert(sna->mode.rr_active);
3125 		sna->mode.rr_active--;
3126 	}
3127 	if (saved_transform)
3128 		sna->mode.rr_active++;
3129 	sna_crtc->transform = saved_transform;
3130 	sna_crtc->cursor_transform = saved_cursor_transform;
3131 	sna_crtc->hwcursor = saved_hwcursor;
3132 	sna_crtc->bo = saved_bo;
3133 
3134 	reprobe_connectors(crtc);
3135 	return FALSE;
3136 }
3137 
3138 static Bool
sna_crtc_set_mode_major(xf86CrtcPtr crtc,DisplayModePtr mode,Rotation rotation,int x,int y)3139 sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
3140 			Rotation rotation, int x, int y)
3141 {
3142 	struct sna *sna = to_sna(crtc->scrn);
3143 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
3144 	struct drm_mode_modeinfo saved_kmode;
3145 	char outputs[256];
3146 
3147 	if (mode->HDisplay == 0 || mode->VDisplay == 0)
3148 		return FALSE;
3149 
3150 	assert(sna_crtc);
3151 
3152 	xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO,
3153 		   "switch to mode %dx%d@%.1f on %s using pipe %d, position (%d, %d), rotation %s, reflection %s\n",
3154 		   mode->HDisplay, mode->VDisplay, xf86ModeVRefresh(mode),
3155 		   outputs_for_crtc(crtc, outputs, sizeof(outputs)), __sna_crtc_pipe(sna_crtc),
3156 		   x, y, rotation_to_str(rotation), reflection_to_str(rotation));
3157 
3158 	assert(mode->HDisplay <= sna->mode.max_crtc_width &&
3159 	       mode->VDisplay <= sna->mode.max_crtc_height);
3160 
3161 #if HAS_GAMMA
3162 	sna_crtc_gamma_set(crtc,
3163 			   crtc->gamma_red, crtc->gamma_green,
3164 			   crtc->gamma_blue, crtc->gamma_size);
3165 #endif
3166 
3167 	saved_kmode = sna_crtc->kmode;
3168 	mode_to_kmode(&sna_crtc->kmode, mode);
3169 	if (__sna_crtc_set_mode(crtc))
3170 		return TRUE;
3171 
3172 	sna_crtc->kmode = saved_kmode;
3173 	return FALSE;
3174 }
3175 
3176 static void
sna_crtc_dpms(xf86CrtcPtr crtc,int mode)3177 sna_crtc_dpms(xf86CrtcPtr crtc, int mode)
3178 {
3179 	DBG(("%s(pipe %d, dpms mode -> %d):= active=%d\n",
3180 	     __FUNCTION__, sna_crtc_pipe(crtc), mode, mode == DPMSModeOn));
3181 
3182 	if (mode == DPMSModeOn && crtc->enabled) {
3183 		if (__sna_crtc_set_mode(crtc))
3184 			update_flush_interval(to_sna(crtc->scrn));
3185 		else
3186 			mode = DPMSModeOff;
3187 	}
3188 
3189 	if (mode != DPMSModeOn)
3190 		sna_crtc_disable(crtc, false);
3191 }
3192 
sna_mode_adjust_frame(struct sna * sna,int x,int y)3193 void sna_mode_adjust_frame(struct sna *sna, int x, int y)
3194 {
3195 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
3196 	xf86CrtcPtr crtc;
3197 	int saved_x, saved_y;
3198 
3199 	if ((unsigned)config->compat_output >= config->num_output)
3200 		return;
3201 
3202 	crtc = config->output[config->compat_output]->crtc;
3203 	if (crtc == NULL || !crtc->enabled)
3204 		return;
3205 
3206 	if (crtc->x == x && crtc->y == y)
3207 		return;
3208 
3209 	saved_x = crtc->x;
3210 	saved_y = crtc->y;
3211 
3212 	crtc->x = x;
3213 	crtc->y = y;
3214 	if (to_sna_crtc(crtc) && !__sna_crtc_set_mode(crtc)) {
3215 		crtc->x = saved_x;
3216 		crtc->y = saved_y;
3217 	}
3218 }
3219 
3220 static void
sna_crtc_gamma_set(xf86CrtcPtr crtc,CARD16 * red,CARD16 * green,CARD16 * blue,int size)3221 sna_crtc_gamma_set(xf86CrtcPtr crtc,
3222 		   CARD16 *red, CARD16 *green, CARD16 *blue, int size)
3223 {
3224 	struct sna *sna = to_sna(crtc->scrn);
3225 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
3226 	struct drm_color_lut *lut = sna_crtc->gamma_lut;
3227 	uint32_t blob_size = size * sizeof(lut[0]);
3228 	uint32_t blob_id;
3229 	int ret, i;
3230 
3231 	DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
3232 
3233 	if (!lut) {
3234 		assert(size == 256);
3235 
3236 		drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
3237 				    sna_crtc_id(crtc),
3238 				    size, red, green, blue);
3239 		return;
3240 	}
3241 
3242 	assert(size == sna_crtc->gamma_lut_size);
3243 
3244 	for (i = 0; i < size; i++) {
3245 		lut[i].red = red[i];
3246 		lut[i].green = green[i];
3247 		lut[i].blue = blue[i];
3248 	}
3249 
3250 	ret = drmModeCreatePropertyBlob(sna->kgem.fd, lut, blob_size, &blob_id);
3251 	if (ret)
3252 		return;
3253 
3254 	ret = drmModeObjectSetProperty(sna->kgem.fd,
3255 				       sna_crtc->id, DRM_MODE_OBJECT_CRTC,
3256 				       sna_crtc->gamma_lut_prop,
3257 				       blob_id);
3258 
3259 	drmModeDestroyPropertyBlob(sna->kgem.fd, blob_id);
3260 }
3261 
3262 static void
sna_crtc_destroy(xf86CrtcPtr crtc)3263 sna_crtc_destroy(xf86CrtcPtr crtc)
3264 {
3265 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
3266 	struct plane *sprite, *sn;
3267 
3268 	if (sna_crtc == NULL)
3269 		return;
3270 
3271 	free(sna_crtc->gamma_lut);
3272 
3273 	list_for_each_entry_safe(sprite, sn, &sna_crtc->sprites, link)
3274 		free(sprite);
3275 
3276 	free(sna_crtc);
3277 	crtc->driver_private = NULL;
3278 }
3279 
3280 #if HAS_PIXMAP_SHARING
3281 static Bool
sna_crtc_set_scanout_pixmap(xf86CrtcPtr crtc,PixmapPtr pixmap)3282 sna_crtc_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap)
3283 {
3284 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
3285 
3286 	if (sna_crtc == NULL)
3287 		return FALSE;
3288 
3289 	if (pixmap == sna_crtc->slave_pixmap)
3290 		return TRUE;
3291 
3292 	DBG(("%s: CRTC:%d, pipe=%d setting scanout pixmap=%ld\n",
3293 	     __FUNCTION__, __sna_crtc_id(sna_crtc),  __sna_crtc_pipe(sna_crtc),
3294 	     pixmap ? pixmap->drawable.serialNumber : 0));
3295 
3296 	/* Disable first so that we can unregister the damage tracking */
3297 	sna_crtc_disable_shadow(to_sna(crtc->scrn), sna_crtc);
3298 
3299 	sna_crtc->slave_pixmap = pixmap;
3300 
3301 	return TRUE;
3302 }
3303 #endif
3304 
3305 static const xf86CrtcFuncsRec sna_crtc_funcs = {
3306 #if XF86_CRTC_VERSION >= 1
3307 	.dpms = sna_crtc_dpms,
3308 #endif
3309 	.set_mode_major = sna_crtc_set_mode_major,
3310 	.gamma_set = sna_crtc_gamma_set,
3311 	.destroy = sna_crtc_destroy,
3312 #if HAS_PIXMAP_SHARING
3313 	.set_scanout_pixmap = sna_crtc_set_scanout_pixmap,
3314 #endif
3315 };
3316 
prop_has_type_and_name(const struct drm_mode_get_property * prop,unsigned int type,const char * name)3317 inline static bool prop_has_type_and_name(const struct drm_mode_get_property *prop,
3318 					  unsigned int type, const char *name)
3319 {
3320 	if ((prop->flags & (1 << type)) == 0)
3321 		return false;
3322 
3323 	if (strcmp(prop->name, name))
3324 		return false;
3325 
3326 	return true;
3327 }
3328 
prop_is_rotation(const struct drm_mode_get_property * prop)3329 inline static bool prop_is_rotation(const struct drm_mode_get_property *prop)
3330 {
3331 	return prop_has_type_and_name(prop, 5, "rotation");
3332 }
3333 
parse_rotation_prop(struct sna * sna,struct plane * p,struct drm_mode_get_property * prop,uint64_t value)3334 static void parse_rotation_prop(struct sna *sna, struct plane *p,
3335 				struct drm_mode_get_property *prop,
3336 				uint64_t value)
3337 {
3338 	struct drm_mode_property_enum *enums;
3339 	int j;
3340 
3341 	p->rotation.prop = prop->prop_id;
3342 	p->rotation.current = value;
3343 
3344 	DBG(("%s: found rotation property .id=%d, value=%ld, num_enums=%d\n",
3345 	     __FUNCTION__, prop->prop_id, value, prop->count_enum_blobs));
3346 
3347 	enums = malloc(prop->count_enum_blobs * sizeof(struct drm_mode_property_enum));
3348 	if (!enums)
3349 		return;
3350 
3351 	prop->count_values = 0;
3352 	prop->enum_blob_ptr = (uintptr_t)enums;
3353 
3354 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, prop)) {
3355 		free(enums);
3356 		return;
3357 	}
3358 
3359 	/* XXX we assume that the mapping between kernel enum and
3360 	 * RandR remains fixed for our lifetimes.
3361 	 */
3362 	VG(VALGRIND_MAKE_MEM_DEFINED(enums, sizeof(*enums)*prop->count_enum_blobs));
3363 	for (j = 0; j < prop->count_enum_blobs; j++) {
3364 		DBG(("%s: rotation[%d] = %s [%lx]\n", __FUNCTION__,
3365 		     j, enums[j].name, (long)enums[j].value));
3366 		p->rotation.supported |= 1 << enums[j].value;
3367 	}
3368 
3369 	free(enums);
3370 }
3371 
prop_is_color_encoding(const struct drm_mode_get_property * prop)3372 inline static bool prop_is_color_encoding(const struct drm_mode_get_property *prop)
3373 {
3374 	return prop_has_type_and_name(prop, 3, "COLOR_ENCODING");
3375 }
3376 
parse_color_encoding_prop(struct sna * sna,struct plane * p,struct drm_mode_get_property * prop,uint64_t value)3377 static void parse_color_encoding_prop(struct sna *sna, struct plane *p,
3378 				      struct drm_mode_get_property *prop,
3379 				      uint64_t value)
3380 {
3381 	struct drm_mode_property_enum *enums;
3382 	unsigned int supported = 0;
3383 	int j;
3384 
3385 	DBG(("%s: found color encoding property .id=%d, value=%ld, num_enums=%d\n",
3386 	     __FUNCTION__, prop->prop_id, (long)value, prop->count_enum_blobs));
3387 
3388 	enums = malloc(prop->count_enum_blobs * sizeof(struct drm_mode_property_enum));
3389 	if (!enums)
3390 		return;
3391 
3392 	prop->count_values = 0;
3393 	prop->enum_blob_ptr = (uintptr_t)enums;
3394 
3395 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, prop)) {
3396 		free(enums);
3397 		return;
3398 	}
3399 
3400 	VG(VALGRIND_MAKE_MEM_DEFINED(enums, sizeof(*enums)*prop->count_enum_blobs));
3401 	for (j = 0; j < prop->count_enum_blobs; j++) {
3402 		if (!strcmp(enums[j].name, "ITU-R BT.601 YCbCr")) {
3403 			p->color_encoding.values[0] = enums[j].value;
3404 			supported |= 1 << 0;
3405 		} else if (!strcmp(enums[j].name, "ITU-R BT.709 YCbCr")) {
3406 			p->color_encoding.values[1] = enums[j].value;
3407 			supported |= 1 << 1;
3408 		}
3409 	}
3410 
3411 	free(enums);
3412 
3413 	if (supported == 3)
3414 		p->color_encoding.prop = prop->prop_id;
3415 }
3416 
sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc,unsigned idx,int colorspace)3417 void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc,
3418 				    unsigned idx, int colorspace)
3419 {
3420 	struct plane *p;
3421 
3422 	assert(to_sna_crtc(crtc));
3423 	assert(colorspace < ARRAY_SIZE(p->color_encoding.values));
3424 
3425 	p = lookup_sprite(to_sna_crtc(crtc), idx);
3426 
3427 	if (!p->color_encoding.prop)
3428 		return;
3429 
3430 	drmModeObjectSetProperty(to_sna(crtc->scrn)->kgem.fd,
3431 				 p->id, DRM_MODE_OBJECT_PLANE,
3432 				 p->color_encoding.prop,
3433 				 p->color_encoding.values[colorspace]);
3434 }
3435 
3436 typedef void (*parse_prop_func)(struct sna *sna,
3437 				struct drm_mode_get_property *prop,
3438 				uint64_t value,
3439 				void *data);
parse_props(struct sna * sna,uint32_t obj_type,uint32_t obj_id,parse_prop_func parse_prop,void * data)3440 static void parse_props(struct sna *sna,
3441 		       uint32_t obj_type, uint32_t obj_id,
3442 		       parse_prop_func parse_prop,
3443 		       void *data)
3444 {
3445 #define N_STACK_PROPS 32 /* must be a multiple of 2 */
3446 	struct local_mode_obj_get_properties arg;
3447 	uint64_t stack[N_STACK_PROPS + N_STACK_PROPS/2];
3448 	uint64_t *values = stack;
3449 	uint32_t *props = (uint32_t *)(values + N_STACK_PROPS);
3450 	int i;
3451 
3452 	memset(&arg, 0, sizeof(struct local_mode_obj_get_properties));
3453 	arg.obj_id = obj_id;
3454 	arg.obj_type = obj_type;
3455 
3456 	arg.props_ptr = (uintptr_t)props;
3457 	arg.prop_values_ptr = (uintptr_t)values;
3458 	arg.count_props = N_STACK_PROPS;
3459 
3460 	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg))
3461 		return;
3462 
3463 	DBG(("%s: object %d (type %x) has %d props\n", __FUNCTION__,
3464 	     obj_id, obj_type, arg.count_props));
3465 
3466 	if (arg.count_props > N_STACK_PROPS) {
3467 		values = malloc(2*sizeof(uint64_t)*arg.count_props);
3468 		if (values == NULL)
3469 			return;
3470 
3471 		props = (uint32_t *)(values + arg.count_props);
3472 
3473 		arg.props_ptr = (uintptr_t)props;
3474 		arg.prop_values_ptr = (uintptr_t)values;
3475 
3476 		if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg))
3477 			arg.count_props = 0;
3478 	}
3479 	VG(VALGRIND_MAKE_MEM_DEFINED(arg.props_ptr, sizeof(uint32_t)*arg.count_props));
3480 	VG(VALGRIND_MAKE_MEM_DEFINED(arg.prop_values_ptr, sizeof(uint64_t)*arg.count_props));
3481 
3482 	for (i = 0; i < arg.count_props; i++) {
3483 		struct drm_mode_get_property prop;
3484 
3485 		memset(&prop, 0, sizeof(prop));
3486 		prop.prop_id = props[i];
3487 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) {
3488 			ERR(("%s: prop[%d].id=%d GETPROPERTY failed with errno=%d\n",
3489 			     __FUNCTION__, i, props[i], errno));
3490 			continue;
3491 		}
3492 
3493 		DBG(("%s: prop[%d] .id=%ld, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i,
3494 		     (long)props[i], prop.name, (unsigned)prop.flags, (long)values[i]));
3495 
3496 		parse_prop(sna, &prop, values[i], data);
3497 	}
3498 
3499 	if (values != stack)
3500 		free(values);
3501 
3502 #undef N_STACK_PROPS
3503 }
3504 
prop_is_type(const struct drm_mode_get_property * prop)3505 static bool prop_is_type(const struct drm_mode_get_property *prop)
3506 {
3507 	return prop_has_type_and_name(prop, 3, "type");
3508 }
3509 
plane_parse_prop(struct sna * sna,struct drm_mode_get_property * prop,uint64_t value,void * data)3510 static void plane_parse_prop(struct sna *sna,
3511 			     struct drm_mode_get_property *prop,
3512 			     uint64_t value, void *data)
3513 {
3514 	struct plane *p = data;
3515 
3516 	if (prop_is_type(prop))
3517 		p->type = value;
3518 	else if (prop_is_rotation(prop))
3519 		parse_rotation_prop(sna, p, prop, value);
3520 	else if (prop_is_color_encoding(prop))
3521 		parse_color_encoding_prop(sna, p, prop, value);
3522 }
3523 
plane_details(struct sna * sna,struct plane * p)3524 static int plane_details(struct sna *sna, struct plane *p)
3525 {
3526 	parse_props(sna, LOCAL_MODE_OBJECT_PLANE, p->id,
3527 		    plane_parse_prop, p);
3528 
3529 	p->rotation.supported &= DBG_NATIVE_ROTATION;
3530 	if (!xf86ReturnOptValBool(sna->Options, OPTION_ROTATION, TRUE))
3531 		p->rotation.supported = RR_Rotate_0;
3532 
3533 	DBG(("%s: plane=%d type=%d\n", __FUNCTION__, p->id, p->type));
3534 
3535 	return p->type;
3536 }
3537 
add_sprite_plane(struct sna_crtc * crtc,struct plane * details)3538 static void add_sprite_plane(struct sna_crtc *crtc,
3539 			     struct plane *details)
3540 {
3541 	struct plane *sprite = malloc(sizeof(*sprite));
3542 	if (!sprite)
3543 		return;
3544 
3545 	memcpy(sprite, details, sizeof(*sprite));
3546 	list_add_tail(&sprite->link, &crtc->sprites);
3547 }
3548 
3549 static void
sna_crtc_find_planes(struct sna * sna,struct sna_crtc * crtc)3550 sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc)
3551 {
3552 #define LOCAL_IOCTL_SET_CAP	DRM_IOWR(0x0d, struct local_set_cap)
3553 	struct local_set_cap {
3554 		uint64_t name;
3555 		uint64_t value;
3556 	} cap;
3557 	struct local_mode_get_plane_res r;
3558 	uint32_t stack_planes[32];
3559 	uint32_t *planes = stack_planes;
3560 	int i;
3561 
3562 	VG_CLEAR(cap);
3563 	cap.name = DRM_CLIENT_CAP_UNIVERSAL_PLANES;
3564 	cap.value = 1;
3565 	(void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_SET_CAP, &cap);
3566 
3567 	VG_CLEAR(r);
3568 	r.plane_id_ptr = (uintptr_t)planes;
3569 	r.count_planes = ARRAY_SIZE(stack_planes);
3570 	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANERESOURCES, &r)) {
3571 		ERR(("%s: GETPLANERESOURCES failed with errno=%d\n", __FUNCTION__, errno));
3572 		return;
3573 	}
3574 
3575 	DBG(("%s: %d planes\n", __FUNCTION__, (int)r.count_planes));
3576 
3577 	if (r.count_planes > ARRAY_SIZE(stack_planes)) {
3578 		planes = malloc(sizeof(uint32_t)*r.count_planes);
3579 		if (planes == NULL)
3580 			return;
3581 
3582 		r.plane_id_ptr = (uintptr_t)planes;
3583 		if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANERESOURCES, &r))
3584 			r.count_planes = 0;
3585 	}
3586 
3587 	VG(VALGRIND_MAKE_MEM_DEFINED(planes, sizeof(uint32_t)*r.count_planes));
3588 
3589 	for (i = 0; i < r.count_planes; i++) {
3590 		struct local_mode_get_plane p;
3591 		struct plane details;
3592 
3593 		VG_CLEAR(p);
3594 		p.plane_id = planes[i];
3595 		p.count_format_types = 0;
3596 		if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANE, &p))
3597 			continue;
3598 
3599 		if ((p.possible_crtcs & (1 << __sna_crtc_pipe(crtc))) == 0)
3600 			continue;
3601 
3602 		DBG(("%s: plane %d is attached to our pipe=%d\n",
3603 		     __FUNCTION__, planes[i], __sna_crtc_pipe(crtc)));
3604 
3605 		details.id = p.plane_id;
3606 		details.rotation.prop = 0;
3607 		details.rotation.supported = RR_Rotate_0;
3608 		details.rotation.current = RR_Rotate_0;
3609 
3610 		switch (plane_details(sna, &details)) {
3611 		default:
3612 			break;
3613 
3614 		case DRM_PLANE_TYPE_PRIMARY:
3615 			crtc->primary = details;
3616 			break;
3617 
3618 		case DRM_PLANE_TYPE_CURSOR:
3619 			break;
3620 
3621 		case DRM_PLANE_TYPE_OVERLAY:
3622 			add_sprite_plane(crtc, &details);
3623 			break;
3624 		}
3625 	}
3626 
3627 	if (planes != stack_planes)
3628 		free(planes);
3629 }
3630 
plane_has_format(const uint32_t formats[],int count_formats,uint32_t format)3631 static bool plane_has_format(const uint32_t formats[],
3632 			     int count_formats,
3633 			     uint32_t format)
3634 {
3635 	int i;
3636 
3637 	for (i = 0; i < count_formats; i++) {
3638 		if (formats[i] == format)
3639 			return true;
3640 	}
3641 
3642 	return false;
3643 }
3644 
sna_has_sprite_format(struct sna * sna,uint32_t format)3645 bool sna_has_sprite_format(struct sna *sna, uint32_t format)
3646 {
3647 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
3648 	int i;
3649 
3650 	if (sna->mode.num_real_crtc == 0)
3651 		return false;
3652 
3653 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
3654 		struct sna_crtc *sna_crtc = to_sna_crtc(config->crtc[i]);
3655 		struct plane *plane;
3656 
3657 		list_for_each_entry(plane, &sna_crtc->sprites, link) {
3658 			struct local_mode_get_plane p;
3659 			uint32_t *formats;
3660 			int count_formats;
3661 			bool has_format;
3662 
3663 			VG_CLEAR(p);
3664 			p.plane_id = plane->id;
3665 			p.count_format_types = 0;
3666 			if (drmIoctl(sna->kgem.fd,
3667 				     LOCAL_IOCTL_MODE_GETPLANE,
3668 				     &p))
3669 				continue;
3670 			count_formats = p.count_format_types;
3671 
3672 			formats = calloc(count_formats, sizeof(formats[0]));
3673 			if (!formats)
3674 				continue;
3675 
3676 			p.count_format_types = count_formats;
3677 			p.format_type_ptr = (uintptr_t)formats;
3678 			if (drmIoctl(sna->kgem.fd,
3679 				     LOCAL_IOCTL_MODE_GETPLANE,
3680 				     &p)) {
3681 				free(formats);
3682 				continue;
3683 			}
3684 
3685 			assert(p.count_format_types == count_formats);
3686 
3687 			has_format = plane_has_format(formats,
3688 						      count_formats,
3689 						      format);
3690 
3691 			free(formats);
3692 
3693 			/*
3694 			 * As long as one plane supports the
3695 			 * format we declare it as supported.
3696 			 * Not all planes may support it, but
3697 			 * then the GPU fallback will kick in.
3698 			 */
3699 			if (has_format)
3700 				return true;
3701 		}
3702 	}
3703 
3704 	return false;
3705 }
3706 
prop_is_gamma_lut(const struct drm_mode_get_property * prop)3707 inline static bool prop_is_gamma_lut(const struct drm_mode_get_property *prop)
3708 {
3709 	return prop_has_type_and_name(prop, 4, "GAMMA_LUT");
3710 }
3711 
prop_is_gamma_lut_size(const struct drm_mode_get_property * prop)3712 inline static bool prop_is_gamma_lut_size(const struct drm_mode_get_property *prop)
3713 {
3714 	return prop_has_type_and_name(prop, 1, "GAMMA_LUT_SIZE");
3715 }
3716 
sna_crtc_parse_prop(struct sna * sna,struct drm_mode_get_property * prop,uint64_t value,void * data)3717 static void sna_crtc_parse_prop(struct sna *sna,
3718 				struct drm_mode_get_property *prop,
3719 				uint64_t value, void *data)
3720 {
3721 	struct sna_crtc *crtc = data;
3722 
3723 	if (prop_is_gamma_lut(prop)) {
3724 		crtc->gamma_lut_prop = prop->prop_id;
3725 		crtc->gamma_lut_blob = value;
3726 	} else if (prop_is_gamma_lut_size(prop)) {
3727 		crtc->gamma_lut_size = value;
3728 	}
3729 }
3730 
3731 static void
sna_crtc_init__props(struct sna * sna,struct sna_crtc * crtc)3732 sna_crtc_init__props(struct sna *sna, struct sna_crtc *crtc)
3733 {
3734 	ScrnInfoPtr scrn = sna->scrn;
3735 
3736 	parse_props(sna, LOCAL_MODE_OBJECT_CRTC, crtc->id,
3737 		    sna_crtc_parse_prop, crtc);
3738 
3739 	/* use high precision gamma LUT for > 8bpc */
3740 	/* X-Server < 1.20 mishandles > 256 slots / > 8 bpc color maps. */
3741 	if (scrn->rgbBits <= 8 ||
3742 	    XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,20,0,0,0))
3743 		crtc->gamma_lut_size = 0;
3744 
3745 	if (crtc->gamma_lut_size) {
3746 		crtc->gamma_lut = calloc(max(crtc->gamma_lut_size, 256),
3747 					 sizeof(crtc->gamma_lut[0]));
3748 		if (!crtc->gamma_lut)
3749 			crtc->gamma_lut_size = 0;
3750 	}
3751 
3752 	DBG(("%s: CRTC:%d, gamma_lut_size=%d\n", __FUNCTION__,
3753 	     __sna_crtc_id(crtc), crtc->gamma_lut_size));
3754 }
3755 
3756 static void
sna_crtc_init__rotation(struct sna * sna,struct sna_crtc * crtc)3757 sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc)
3758 {
3759 	crtc->rotation = RR_Rotate_0;
3760 	crtc->primary.rotation.supported = RR_Rotate_0;
3761 	crtc->primary.rotation.current = RR_Rotate_0;
3762 }
3763 
3764 static void
sna_crtc_init__cursor(struct sna * sna,struct sna_crtc * crtc)3765 sna_crtc_init__cursor(struct sna *sna, struct sna_crtc *crtc)
3766 {
3767 	struct drm_mode_cursor arg;
3768 
3769 	VG_CLEAR(arg);
3770 	arg.flags = DRM_MODE_CURSOR_BO;
3771 	arg.crtc_id = __sna_crtc_id(crtc);
3772 	arg.width = arg.height = 0;
3773 	arg.handle = 0;
3774 
3775 	(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg);
3776 	crtc->hwcursor = true;
3777 }
3778 
3779 static bool
sna_crtc_add(ScrnInfoPtr scrn,unsigned id)3780 sna_crtc_add(ScrnInfoPtr scrn, unsigned id)
3781 {
3782 	struct sna *sna = to_sna(scrn);
3783 	xf86CrtcPtr crtc;
3784 	struct sna_crtc *sna_crtc;
3785 	struct drm_i915_get_pipe_from_crtc_id get_pipe;
3786 
3787 	DBG(("%s(%d): is-zaphod? %d\n", __FUNCTION__, id, is_zaphod(scrn)));
3788 
3789 	sna_crtc = calloc(sizeof(struct sna_crtc), 1);
3790 	if (sna_crtc == NULL)
3791 		return false;
3792 
3793 	list_init(&sna_crtc->public.vblank_queue);
3794 	sna_crtc->id = id;
3795 
3796 	VG_CLEAR(get_pipe);
3797 	get_pipe.pipe = 0;
3798 	get_pipe.crtc_id = id;
3799 	if (drmIoctl(sna->kgem.fd,
3800 		     DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID,
3801 		     &get_pipe)) {
3802 		free(sna_crtc);
3803 		return false;
3804 	}
3805 	assert((unsigned)get_pipe.pipe < 256);
3806 	sna_crtc->public.flags |= get_pipe.pipe << 8;
3807 
3808 	if (is_zaphod(scrn) &&
3809 	    (get_zaphod_crtcs(sna) & (1 << get_pipe.pipe)) == 0) {
3810 		free(sna_crtc);
3811 		return true;
3812 	}
3813 
3814 	list_init(&sna_crtc->sprites);
3815 	sna_crtc_init__rotation(sna, sna_crtc);
3816 
3817 	sna_crtc_init__props(sna, sna_crtc);
3818 
3819 	sna_crtc_find_planes(sna, sna_crtc);
3820 
3821 	DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x\n",
3822 	     __FUNCTION__, id, get_pipe.pipe,
3823 	     sna_crtc->primary.id, sna_crtc->primary.rotation.supported, sna_crtc->primary.rotation.current));
3824 
3825 	list_init(&sna_crtc->shadow_link);
3826 
3827 	crtc = xf86CrtcCreate(scrn, &sna_crtc_funcs);
3828 	if (crtc == NULL) {
3829 		free(sna_crtc);
3830 		return false;
3831 	}
3832 
3833 	sna_crtc_init__cursor(sna, sna_crtc);
3834 
3835 	crtc->driver_private = sna_crtc;
3836 	sna_crtc->base = crtc;
3837 	DBG(("%s: attached crtc[%d] pipe=%d\n",
3838 	     __FUNCTION__, id, __sna_crtc_pipe(sna_crtc)));
3839 
3840 	return true;
3841 }
3842 
3843 static bool
is_panel(int type)3844 is_panel(int type)
3845 {
3846 #define DRM_MODE_CONNECTOR_LVDS 7
3847 #define DRM_MODE_CONNECTOR_eDP 14
3848 #define DRM_MODE_CONNECTOR_DSI 16
3849 	return (type == DRM_MODE_CONNECTOR_LVDS ||
3850 		type == DRM_MODE_CONNECTOR_eDP ||
3851 		type == DRM_MODE_CONNECTOR_DSI);
3852 }
3853 
3854 static int
find_property(struct sna * sna,struct sna_output * output,const char * name)3855 find_property(struct sna *sna, struct sna_output *output, const char *name)
3856 {
3857 	struct drm_mode_get_property prop;
3858 	int i;
3859 
3860 	VG_CLEAR(prop);
3861 	for (i = 0; i < output->num_props; i++) {
3862 		prop.prop_id = output->prop_ids[i];
3863 		prop.count_values = 0;
3864 		prop.count_enum_blobs = 0;
3865 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
3866 			continue;
3867 
3868 		if (strcmp(prop.name, name) == 0)
3869 			return i;
3870 	}
3871 
3872 	return -1;
3873 }
3874 
update_properties(struct sna * sna,struct sna_output * output)3875 static void update_properties(struct sna *sna, struct sna_output *output)
3876 {
3877 	union compat_mode_get_connector compat_conn;
3878 	struct drm_mode_modeinfo dummy;
3879 
3880 	VG_CLEAR(compat_conn);
3881 
3882 	compat_conn.conn.connector_id = output->id;
3883 	compat_conn.conn.count_props = output->num_props;
3884 	compat_conn.conn.props_ptr = (uintptr_t)output->prop_ids;
3885 	compat_conn.conn.prop_values_ptr = (uintptr_t)output->prop_values;
3886 	compat_conn.conn.count_modes = 1; /* skip detect */
3887 	compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
3888 	compat_conn.conn.count_encoders = 0;
3889 
3890 	(void)drmIoctl(sna->kgem.fd,
3891 		       DRM_IOCTL_MODE_GETCONNECTOR,
3892 		       &compat_conn.conn);
3893 
3894 	assert(compat_conn.conn.count_props == output->num_props);
3895 	output->update_properties = false;
3896 }
3897 
3898 static xf86OutputStatus
sna_output_detect(xf86OutputPtr output)3899 sna_output_detect(xf86OutputPtr output)
3900 {
3901 	struct sna *sna = to_sna(output->scrn);
3902 	struct sna_output *sna_output = output->driver_private;
3903 	union compat_mode_get_connector compat_conn;
3904 	uint32_t now;
3905 
3906 	DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id));
3907 	sna_output->update_properties = false;
3908 
3909 	if (!sna_output->id) {
3910 		DBG(("%s(%s) hiding due to lost connection\n", __FUNCTION__, output->name));
3911 		return XF86OutputStatusDisconnected;
3912 	}
3913 
3914 	/* Cache detections for 15s or hotplug event  */
3915 	now = GetTimeInMillis();
3916 	if (sna_output->last_detect != 0 &&
3917 	    (int32_t)(now - sna_output->last_detect) <= OUTPUT_STATUS_CACHE_MS) {
3918 		DBG(("%s(%s) reporting cached status (since %dms): %d\n",
3919 		     __FUNCTION__, output->name, now - sna_output->last_detect,
3920 		     sna_output->status));
3921 		sna_output->update_properties = true;
3922 		return sna_output->status;
3923 	}
3924 
3925 	VG_CLEAR(compat_conn);
3926 	compat_conn.conn.connector_id = sna_output->id;
3927 	sna_output->num_modes = compat_conn.conn.count_modes = 0; /* reprobe */
3928 	compat_conn.conn.count_encoders = 0;
3929 	compat_conn.conn.count_props = sna_output->num_props;
3930 	compat_conn.conn.props_ptr = (uintptr_t)sna_output->prop_ids;
3931 	compat_conn.conn.prop_values_ptr = (uintptr_t)sna_output->prop_values;
3932 
3933 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn))
3934 		return XF86OutputStatusUnknown;
3935 	DBG(("%s(%s): num modes %d -> %d, num props %d -> %d\n",
3936 	     __FUNCTION__, output->name,
3937 	     sna_output->num_modes, compat_conn.conn.count_modes,
3938 	     sna_output->num_props, compat_conn.conn.count_props));
3939 
3940 	assert(compat_conn.conn.count_props == sna_output->num_props);
3941 
3942 	while (compat_conn.conn.count_modes && compat_conn.conn.count_modes != sna_output->num_modes) {
3943 		struct drm_mode_modeinfo *new_modes;
3944 		int old_count;
3945 
3946 		old_count = sna_output->num_modes;
3947 		new_modes = realloc(sna_output->modes,
3948 				    sizeof(*sna_output->modes)*compat_conn.conn.count_modes);
3949 		if (new_modes == NULL)
3950 			break;
3951 
3952 		sna_output->modes = new_modes;
3953 		sna_output->num_modes = compat_conn.conn.count_modes;
3954 		compat_conn.conn.modes_ptr = (uintptr_t)sna_output->modes;
3955 		compat_conn.conn.count_encoders = 0;
3956 		compat_conn.conn.count_props = 0;
3957 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
3958 			sna_output->num_modes = min(old_count, sna_output->num_modes);
3959 			break;
3960 		}
3961 		VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->modes, sizeof(*sna_output->modes)*sna_output->num_modes));
3962 	}
3963 
3964 	DBG(("%s(%s): found %d modes, connection status=%d\n",
3965 	     __FUNCTION__, output->name, sna_output->num_modes, compat_conn.conn.connection));
3966 
3967 	sna_output->reprobe = false;
3968 	sna_output->last_detect = now;
3969 	switch (compat_conn.conn.connection) {
3970 	case DRM_MODE_CONNECTED:
3971 		sna_output->status = XF86OutputStatusConnected;
3972 		output->mm_width = compat_conn.conn.mm_width;
3973 		output->mm_height = compat_conn.conn.mm_height;
3974 		break;
3975 	case DRM_MODE_DISCONNECTED:
3976 		sna_output->status = XF86OutputStatusDisconnected;
3977 		break;
3978 	default:
3979 	case DRM_MODE_UNKNOWNCONNECTION:
3980 		sna_output->status = XF86OutputStatusUnknown;
3981 		break;
3982 	}
3983 	return sna_output->status;
3984 }
3985 
3986 static Bool
sna_output_mode_valid(xf86OutputPtr output,DisplayModePtr mode)3987 sna_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
3988 {
3989 	struct sna_output *sna_output = output->driver_private;
3990 	struct sna *sna = to_sna(output->scrn);
3991 
3992 	if (mode->HDisplay > sna->mode.max_crtc_width)
3993 		return MODE_VIRTUAL_X;
3994 	if (mode->VDisplay > sna->mode.max_crtc_height)
3995 		return MODE_VIRTUAL_Y;
3996 
3997 	/* Check that we can successfully pin this into the global GTT */
3998 	if ((kgem_can_create_2d(&sna->kgem,
3999 				mode->HDisplay, mode->VDisplay,
4000 				sna->scrn->bitsPerPixel) & KGEM_CAN_CREATE_GTT) == 0)
4001 		return MODE_MEM_VIRT;
4002 
4003 	/*
4004 	 * If the connector type is a panel, we will use the panel limit to
4005 	 * verfiy whether the mode is valid.
4006 	 */
4007 	if (sna_output->has_panel_limits) {
4008 		if (mode->HDisplay > sna_output->panel_hdisplay ||
4009 		    mode->VDisplay > sna_output->panel_vdisplay)
4010 			return MODE_PANEL;
4011 	}
4012 
4013 	return MODE_OK;
4014 }
4015 
sna_output_set_parsed_edid(xf86OutputPtr output,xf86MonPtr mon)4016 static void sna_output_set_parsed_edid(xf86OutputPtr output, xf86MonPtr mon)
4017 {
4018 	unsigned conn_mm_width, conn_mm_height;
4019 
4020 	/* We set the output size based on values from the kernel */
4021 	conn_mm_width = output->mm_width;
4022 	conn_mm_height = output->mm_height;
4023 
4024 	xf86OutputSetEDID(output, mon);
4025 
4026 	if (output->mm_width != conn_mm_width || output->mm_height != conn_mm_height) {
4027 		DBG(("%s)%s): kernel and Xorg disagree over physical size: kernel=%dx%dmm, Xorg=%dx%dmm\n",
4028 		     __FUNCTION__, output->name,
4029 		     conn_mm_width, conn_mm_height,
4030 		     output->mm_width, output->mm_height));
4031 	}
4032 
4033 	output->mm_width = conn_mm_width;
4034 	output->mm_height = conn_mm_height;
4035 }
4036 
4037 static void
sna_output_attach_edid(xf86OutputPtr output)4038 sna_output_attach_edid(xf86OutputPtr output)
4039 {
4040 	struct sna *sna = to_sna(output->scrn);
4041 	struct sna_output *sna_output = output->driver_private;
4042 	struct drm_mode_get_blob blob;
4043 	void *old, *raw = NULL;
4044 	xf86MonPtr mon = NULL;
4045 
4046 	if (sna_output->edid_idx == -1)
4047 		return;
4048 
4049 	/* Always refresh the blob as the kernel may randomly update the
4050 	 * id even if the contents of the blob doesn't change, and a
4051 	 * request for the stale id will return nothing.
4052 	 */
4053 	if (sna_output->update_properties)
4054 		update_properties(sna, sna_output);
4055 
4056 	raw = sna_output->edid_raw;
4057 	blob.length = sna_output->edid_len;
4058 
4059 	if (blob.length && output->MonInfo) {
4060 		old = alloca(blob.length);
4061 		memcpy(old, raw, blob.length);
4062 	} else
4063 		old = NULL;
4064 
4065 	blob.blob_id = sna_output->prop_values[sna_output->edid_idx];
4066 	if (!blob.blob_id)
4067 		goto done;
4068 
4069 	DBG(("%s(%s): attaching EDID id=%d, current=%d\n",
4070 	     __FUNCTION__, output->name,
4071 	     blob.blob_id, sna_output->edid_blob_id));
4072 	if (blob.blob_id == sna_output->edid_blob_id && 0) { /* sigh */
4073 		if (output->MonInfo) {
4074 			/* XXX the property keeps on disappearing... */
4075 			RRChangeOutputProperty(output->randr_output,
4076 					       MakeAtom("EDID", strlen("EDID"), TRUE),
4077 					       XA_INTEGER, 8, PropModeReplace,
4078 					       sna_output->edid_len,
4079 					       sna_output->edid_raw,
4080 					       FALSE, FALSE);
4081 
4082 			return;
4083 		}
4084 
4085 		goto skip_read;
4086 	}
4087 
4088 	blob.data = (uintptr_t)raw;
4089 	do {
4090 		while (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) {
4091 			update_properties(sna, sna_output);
4092 			if (blob.blob_id == sna_output->prop_values[sna_output->edid_idx]) {
4093 				DBG(("%s(%s): failed to read blob, reusing previous\n",
4094 				     __FUNCTION__, output->name));
4095 				goto done;
4096 			}
4097 			blob.blob_id = sna_output->prop_values[sna_output->edid_idx];
4098 		}
4099 
4100 		DBG(("%s(%s): retrieving blob id=%d, length=%d\n",
4101 		     __FUNCTION__, output->name, blob.blob_id, blob.length));
4102 
4103 		if (blob.length < 128)
4104 			goto done;
4105 
4106 		if (blob.length > sna_output->edid_len) {
4107 			raw = realloc(raw, blob.length);
4108 			if (raw == NULL)
4109 				goto done;
4110 
4111 			VG(memset(raw, 0, blob.length));
4112 			blob.data = (uintptr_t)raw;
4113 		}
4114 	} while (blob.length != sna_output->edid_len &&
4115 		 drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob));
4116 
4117 	if (blob.length & 127) {
4118 		/* Truncated EDID! Make sure no one reads too far */
4119 		*SECTION(NO_EDID, (uint8_t*)raw) = blob.length/128 - 1;
4120 		blob.length &= -128;
4121 	}
4122 
4123 	if (old &&
4124 	    blob.length == sna_output->edid_len &&
4125 	    memcmp(old, raw, blob.length) == 0) {
4126 		DBG(("%s(%s): EDID + MonInfo is unchanged\n",
4127 		     __FUNCTION__, output->name));
4128 		assert(sna_output->edid_raw == raw);
4129 		sna_output->edid_blob_id = blob.blob_id;
4130 		RRChangeOutputProperty(output->randr_output,
4131 				       MakeAtom("EDID", strlen("EDID"), TRUE),
4132 				       XA_INTEGER, 8, PropModeReplace,
4133 				       sna_output->edid_len,
4134 				       sna_output->edid_raw,
4135 				       FALSE, FALSE);
4136 		return;
4137 	}
4138 
4139 skip_read:
4140 	if (raw) {
4141 		mon = xf86InterpretEDID(output->scrn->scrnIndex, raw);
4142 		if (mon && blob.length > 128)
4143 			mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
4144 	}
4145 
4146 done:
4147 	sna_output_set_parsed_edid(output, mon);
4148 	if (raw) {
4149 		sna_output->edid_raw = raw;
4150 		sna_output->edid_len = blob.length;
4151 		sna_output->edid_blob_id = blob.blob_id;
4152 	}
4153 }
4154 
4155 static void
sna_output_attach_tile(xf86OutputPtr output)4156 sna_output_attach_tile(xf86OutputPtr output)
4157 {
4158 #if XF86_OUTPUT_VERSION >= 3
4159 	struct sna *sna = to_sna(output->scrn);
4160 	struct sna_output *sna_output = output->driver_private;
4161 	struct drm_mode_get_blob blob;
4162 	struct xf86CrtcTileInfo tile_info, *set = NULL;
4163 	char *tile;
4164 	int id;
4165 
4166 	id = find_property(sna, sna_output, "TILE");
4167 	DBG(("%s: found? TILE=%d\n", __FUNCTION__, id));
4168 	if (id == -1)
4169 		goto out;
4170 
4171 	if (sna_output->update_properties)
4172 		update_properties(sna, sna_output);
4173 
4174 	VG_CLEAR(blob);
4175 	blob.blob_id = sna_output->prop_values[id];
4176 	blob.length = 0;
4177 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
4178 		goto out;
4179 
4180 	do {
4181 		id = blob.length;
4182 		tile = alloca(id + 1);
4183 		blob.data = (uintptr_t)tile;
4184 		VG(memset(tile, 0, id));
4185 		DBG(("%s: reading %d bytes for TILE blob\n", __FUNCTION__, id));
4186 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
4187 			goto out;
4188 	} while (id != blob.length);
4189 
4190 	tile[blob.length] = '\0'; /* paranoia */
4191 	DBG(("%s: TILE='%s'\n", __FUNCTION__, tile));
4192 	if (xf86OutputParseKMSTile(tile, blob.length, &tile_info))
4193 		set = &tile_info;
4194 out:
4195 	xf86OutputSetTile(output, set);
4196 #endif
4197 }
4198 
duplicate_mode(DisplayModePtr modes,DisplayModePtr m)4199 static bool duplicate_mode(DisplayModePtr modes, DisplayModePtr m)
4200 {
4201 	if (m == NULL)
4202 		return false;
4203 
4204 	while (modes) {
4205 		if (xf86ModesEqual(modes, m))
4206 			return true;
4207 
4208 		modes = modes->next;
4209 	}
4210 
4211 	return false;
4212 }
4213 
4214 static struct pixel_count {
4215 	int16_t width, height;
4216 } common_16_9[] = {
4217 	{ 640, 360 },
4218 	{ 720, 405 },
4219 	{ 864, 486 },
4220 	{ 960, 540 },
4221 	{ 1024, 576 },
4222 	{ 1280, 720 },
4223 	{ 1366, 768 },
4224 	{ 1600, 900 },
4225 	{ 1920, 1080 },
4226 	{ 2048, 1152 },
4227 	{ 2560, 1440 },
4228 	{ 2880, 1620 },
4229 	{ 3200, 1800 },
4230 	{ 3840, 2160 },
4231 	{ 4096, 2304 },
4232 	{ 5120, 2880 },
4233 	{ 7680, 4320 },
4234 	{ 15360, 8640 },
4235 }, common_16_10[] = {
4236 	{ 1280, 800 },
4237 	{ 1400, 900 },
4238 	{ 1680, 1050 },
4239 	{ 1920, 1200 },
4240 	{ 2560, 1600 },
4241 };
4242 
4243 static DisplayModePtr
default_modes(DisplayModePtr preferred)4244 default_modes(DisplayModePtr preferred)
4245 {
4246 	DisplayModePtr modes;
4247 	int n;
4248 
4249 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,6,99,900,0)
4250 	modes = xf86GetDefaultModes();
4251 #else
4252 	modes = xf86GetDefaultModes(0, 0);
4253 #endif
4254 
4255 	/* XXX O(n^2) mode list generation :( */
4256 
4257 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,4,99,901,0)
4258 	if (preferred) {
4259 		DisplayModePtr m;
4260 
4261 		/* Add a half-resolution mode useful for large panels */
4262 		m = xf86GTFMode(preferred->HDisplay/2,
4263 				preferred->VDisplay/2,
4264 				xf86ModeVRefresh(preferred),
4265 				FALSE, FALSE);
4266 		if (!duplicate_mode(modes, m))
4267 			modes = xf86ModesAdd(modes, m);
4268 		else
4269 			free(m);
4270 
4271 		if (preferred->VDisplay * 16 > preferred->HDisplay*9 - preferred->HDisplay/32 &&
4272 		    preferred->VDisplay * 16 < preferred->HDisplay*9 + preferred->HDisplay/32) {
4273 			DBG(("Adding 16:9 modes -- %d < %d > %d\n",
4274 			     preferred->HDisplay*9 - preferred->HDisplay/32,
4275 			     preferred->VDisplay * 16,
4276 			     preferred->HDisplay*9 + preferred->HDisplay/32));
4277 			for (n = 0; n < ARRAY_SIZE(common_16_9); n++) {
4278 				if (preferred->HDisplay <= common_16_9[n].width ||
4279 				    preferred->VDisplay <= common_16_9[n].height)
4280 					break;
4281 
4282 				m = xf86GTFMode(common_16_9[n].width,
4283 						common_16_9[n].height,
4284 						xf86ModeVRefresh(preferred),
4285 						FALSE, FALSE);
4286 				if (!duplicate_mode(modes, m))
4287 					modes = xf86ModesAdd(modes, m);
4288 				else
4289 					free(m);
4290 			}
4291 		}
4292 
4293 		if (preferred->VDisplay * 16 > preferred->HDisplay*10 - preferred->HDisplay/32 &&
4294 		    preferred->VDisplay * 16 < preferred->HDisplay*10 + preferred->HDisplay/32) {
4295 			DBG(("Adding 16:10 modes -- %d < %d > %d\n",
4296 			     preferred->HDisplay*10 - preferred->HDisplay/32,
4297 			     preferred->VDisplay * 16,
4298 			     preferred->HDisplay*10 + preferred->HDisplay/32));
4299 			for (n = 0; n < ARRAY_SIZE(common_16_10); n++) {
4300 				if (preferred->HDisplay <= common_16_10[n].width ||
4301 				    preferred->VDisplay <= common_16_10[n].height)
4302 					break;
4303 
4304 				m = xf86GTFMode(common_16_10[n].width,
4305 						common_16_10[n].height,
4306 						xf86ModeVRefresh(preferred),
4307 						FALSE, FALSE);
4308 				if (!duplicate_mode(modes, m))
4309 					modes = xf86ModesAdd(modes, m);
4310 				else
4311 					free(m);
4312 			}
4313 		}
4314 	}
4315 #endif
4316 
4317 	return modes;
4318 }
4319 
4320 static DisplayModePtr
sna_output_add_default_modes(xf86OutputPtr output,DisplayModePtr modes)4321 sna_output_add_default_modes(xf86OutputPtr output, DisplayModePtr modes)
4322 {
4323 	xf86MonPtr mon = output->MonInfo;
4324 	DisplayModePtr i, m, preferred = NULL;
4325 	int max_x = 0, max_y = 0, max_clock = 0;
4326 	float max_vrefresh = 0.0;
4327 
4328 	if (mon && GTF_SUPPORTED(mon->features.msc))
4329 		return modes;
4330 
4331 	for (m = modes; m; m = m->next) {
4332 		if (m->type & M_T_PREFERRED)
4333 			preferred = m;
4334 		max_x = max(max_x, m->HDisplay);
4335 		max_y = max(max_y, m->VDisplay);
4336 		max_clock = max(max_clock, m->Clock);
4337 		max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m));
4338 	}
4339 	max_vrefresh *= (1 + SYNC_TOLERANCE);
4340 
4341 	m = default_modes(preferred);
4342 	xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0);
4343 
4344 	for (i = m; i; i = i->next) {
4345 		if (i->Clock > max_clock)
4346 			i->status = MODE_CLOCK_HIGH;
4347 		if (xf86ModeVRefresh(i) > max_vrefresh)
4348 			i->status = MODE_VSYNC;
4349 		if (preferred &&
4350 		    i->HDisplay >= preferred->HDisplay &&
4351 		    i->VDisplay >= preferred->VDisplay &&
4352 		    xf86ModeVRefresh(i) >= xf86ModeVRefresh(preferred))
4353 			i->status = MODE_PANEL;
4354 	}
4355 
4356 	xf86PruneInvalidModes(output->scrn, &m, FALSE);
4357 
4358 	return xf86ModesAdd(modes, m);
4359 }
4360 
4361 static DisplayModePtr
sna_output_override_edid(xf86OutputPtr output)4362 sna_output_override_edid(xf86OutputPtr output)
4363 {
4364 	struct sna_output *sna_output = output->driver_private;
4365 	xf86MonPtr mon = NULL;
4366 
4367 	if (sna_output->fake_edid_raw == NULL)
4368 		return NULL;
4369 
4370 	mon = xf86InterpretEDID(output->scrn->scrnIndex, sna_output->fake_edid_raw);
4371 	if (mon == NULL) {
4372 		return NULL;
4373 	}
4374 
4375 	mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
4376 
4377 	xf86OutputSetEDID(output, mon);
4378 
4379 	return xf86DDCGetModes(output->scrn->scrnIndex, mon);
4380 }
4381 
4382 static DisplayModePtr
sna_output_get_modes(xf86OutputPtr output)4383 sna_output_get_modes(xf86OutputPtr output)
4384 {
4385 	struct sna_output *sna_output = output->driver_private;
4386 	DisplayModePtr Modes, current;
4387 	int i;
4388 
4389 	DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id));
4390 	assert(sna_output->id);
4391 
4392 	Modes = sna_output_override_edid(output);
4393 	if (Modes)
4394 		return Modes;
4395 
4396 	sna_output_attach_edid(output);
4397 	sna_output_attach_tile(output);
4398 
4399 	current = NULL;
4400 	if (output->crtc && !sna_output->hotplug_count) {
4401 		struct drm_mode_crtc mode;
4402 
4403 		VG_CLEAR(mode);
4404 		assert(to_sna_crtc(output->crtc));
4405 		mode.crtc_id = sna_crtc_id(output->crtc);
4406 
4407 		if (drmIoctl(to_sna(output->scrn)->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode) == 0) {
4408 			DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__,
4409 			     sna_crtc_id(output->crtc),
4410 			     sna_crtc_pipe(output->crtc),
4411 			     mode.mode_valid && mode.mode.clock));
4412 
4413 			if (mode.mode_valid && mode.mode.clock) {
4414 				current = calloc(1, sizeof(DisplayModeRec));
4415 				if (current) {
4416 					mode_from_kmode(output->scrn, &mode.mode, current);
4417 					current->type |= M_T_DRIVER | M_T_PREFERRED;
4418 				}
4419 			}
4420 		}
4421 	}
4422 
4423 	DBG(("%s: adding %d probed modes\n", __FUNCTION__, sna_output->num_modes));
4424 
4425 	for (i = 0; i < sna_output->num_modes; i++) {
4426 		DisplayModePtr mode;
4427 
4428 		mode = calloc(1, sizeof(DisplayModeRec));
4429 		if (mode == NULL)
4430 			continue;
4431 
4432 		mode = mode_from_kmode(output->scrn,
4433 				       &sna_output->modes[i],
4434 				       mode);
4435 		Modes = xf86ModesAdd(Modes, mode);
4436 		if (current && xf86ModesEqual(mode, current)) {
4437 			free((void*)current->name);
4438 			free(current);
4439 			current = NULL;
4440 		}
4441 		if (current && mode->type & M_T_PREFERRED)
4442 			current->type &= ~M_T_PREFERRED;
4443 	}
4444 
4445 	if (current)
4446 		Modes = xf86ModesAdd(current, Modes);
4447 
4448 	/*
4449 	 * If the connector type is a panel, we will traverse the kernel mode to
4450 	 * get the panel limit. And then add all the standard modes to fake
4451 	 * the fullscreen experience.
4452 	 * If it is incorrect, please fix me.
4453 	 */
4454 	sna_output->has_panel_limits = false;
4455 	if (sna_output->is_panel) {
4456 		sna_output->panel_hdisplay = sna_output->panel_vdisplay = 0;
4457 		for (i = 0; i < sna_output->num_modes; i++) {
4458 			struct drm_mode_modeinfo *m;
4459 
4460 			m = &sna_output->modes[i];
4461 			if (m->hdisplay > sna_output->panel_hdisplay)
4462 				sna_output->panel_hdisplay = m->hdisplay;
4463 			if (m->vdisplay > sna_output->panel_vdisplay)
4464 				sna_output->panel_vdisplay = m->vdisplay;
4465 		}
4466 		sna_output->has_panel_limits =
4467 			sna_output->panel_hdisplay &&
4468 			sna_output->panel_vdisplay;
4469 	}
4470 
4471 	if (sna_output->add_default_modes)
4472 		Modes = sna_output_add_default_modes(output, Modes);
4473 
4474 	return Modes;
4475 }
4476 
4477 static void
sna_output_destroy(xf86OutputPtr output)4478 sna_output_destroy(xf86OutputPtr output)
4479 {
4480 	struct sna_output *sna_output = output->driver_private;
4481 	int i;
4482 
4483 	if (sna_output == NULL)
4484 		return;
4485 
4486 	free(sna_output->edid_raw);
4487 	free(sna_output->fake_edid_raw);
4488 
4489 	for (i = 0; i < sna_output->num_props; i++) {
4490 		if (sna_output->props[i].kprop == NULL)
4491 			continue;
4492 
4493 		if (sna_output->props[i].atoms) {
4494 			if (output->randr_output)
4495 				RRDeleteOutputProperty(output->randr_output, sna_output->props[i].atoms[0]);
4496 			free(sna_output->props[i].atoms);
4497 		}
4498 
4499 		drmModeFreeProperty(sna_output->props[i].kprop);
4500 	}
4501 	free(sna_output->props);
4502 	free(sna_output->prop_ids);
4503 	free(sna_output->prop_values);
4504 
4505 	backlight_close(&sna_output->backlight);
4506 
4507 	free(sna_output);
4508 	output->driver_private = NULL;
4509 }
4510 
4511 static void
__sna_output_dpms(xf86OutputPtr output,int dpms,int fixup)4512 __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup)
4513 {
4514 	struct sna *sna = to_sna(output->scrn);
4515 	struct sna_output *sna_output = output->driver_private;
4516 	int old_dpms = sna_output->dpms_mode;
4517 
4518 	DBG(("%s(%s:%d): dpms=%d (current: %d), active? %d\n",
4519 	     __FUNCTION__, output->name, sna_output->id,
4520 	     dpms, sna_output->dpms_mode,
4521 	     output->crtc != NULL));
4522 
4523 	if (!sna_output->id)
4524 		return;
4525 
4526 	if (old_dpms == dpms)
4527 		return;
4528 
4529 	/* Record the value of the backlight before turning
4530 	 * off the display, and reset if after turning it on.
4531 	 * Order is important as the kernel may record and also
4532 	 * reset the backlight across DPMS. Hence we need to
4533 	 * record the value before the kernel modifies it
4534 	 * and reapply it afterwards.
4535 	 */
4536 	if (sna_output->backlight.iface && dpms != DPMSModeOn) {
4537 		if (old_dpms == DPMSModeOn) {
4538 			sna_output->backlight_active_level = sna_output_backlight_get(output);
4539 			DBG(("%s(%s:%d): saving current backlight %d\n",
4540 			     __FUNCTION__, output->name, sna_output->id,
4541 			     sna_output->backlight_active_level));
4542 		}
4543 		sna_output->dpms_mode = dpms;
4544 		sna_output_backlight_off(sna_output);
4545 	}
4546 
4547 	if (output->crtc &&
4548 	    drmModeConnectorSetProperty(sna->kgem.fd,
4549 					sna_output->id,
4550 					sna_output->dpms_id,
4551 					dpms)) {
4552 		DBG(("%s(%s:%d): failed to set DPMS to %d (fixup? %d)\n",
4553 		     __FUNCTION__, output->name, sna_output->id, dpms, fixup));
4554 		if (fixup && dpms != DPMSModeOn) {
4555 			sna_crtc_disable(output->crtc, false);
4556 			return;
4557 		}
4558 	}
4559 
4560 	if (sna_output->backlight.iface && dpms == DPMSModeOn) {
4561 		DBG(("%s(%d:%d: restoring previous backlight %d\n",
4562 		     __FUNCTION__, output->name, sna_output->id,
4563 		     sna_output->backlight_active_level));
4564 		sna_output_backlight_on(sna_output);
4565 	}
4566 
4567 	sna_output->dpms_mode = dpms;
4568 }
4569 
4570 static void
sna_output_dpms(xf86OutputPtr output,int dpms)4571 sna_output_dpms(xf86OutputPtr output, int dpms)
4572 {
4573 	__sna_output_dpms(output, dpms, true);
4574 }
4575 
4576 static bool
sna_property_ignore(drmModePropertyPtr prop)4577 sna_property_ignore(drmModePropertyPtr prop)
4578 {
4579 	if (!prop)
4580 		return true;
4581 
4582 	/* ignore blob prop */
4583 	if (prop->flags & DRM_MODE_PROP_BLOB)
4584 		return true;
4585 
4586 	/* ignore standard property */
4587 	if (!strcmp(prop->name, "EDID") ||
4588 	    !strcmp(prop->name, "DPMS"))
4589 		return true;
4590 
4591 	return false;
4592 }
4593 
4594 static void
sna_output_create_ranged_atom(xf86OutputPtr output,Atom * atom,const char * name,INT32 min,INT32 max,uint64_t value,Bool immutable)4595 sna_output_create_ranged_atom(xf86OutputPtr output, Atom *atom,
4596 			      const char *name, INT32 min, INT32 max,
4597 			      uint64_t value, Bool immutable)
4598 {
4599 	int err;
4600 	INT32 atom_range[2];
4601 
4602 	atom_range[0] = min;
4603 	atom_range[1] = max;
4604 
4605 	*atom = MakeAtom(name, strlen(name), TRUE);
4606 
4607 	err = RRConfigureOutputProperty(output->randr_output, *atom, FALSE,
4608 					TRUE, immutable, 2, atom_range);
4609 	if (err != 0)
4610 		xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
4611 			   "RRConfigureOutputProperty error, %d\n", err);
4612 
4613 	err = RRChangeOutputProperty(output->randr_output, *atom, XA_INTEGER,
4614 				     32, PropModeReplace, 1, &value,
4615 				     FALSE, FALSE);
4616 	if (err != 0)
4617 		xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
4618 			   "RRChangeOutputProperty error, %d\n", err);
4619 }
4620 
4621 static void
sna_output_create_resources(xf86OutputPtr output)4622 sna_output_create_resources(xf86OutputPtr output)
4623 {
4624 	struct sna *sna = to_sna(output->scrn);
4625 	struct sna_output *sna_output = output->driver_private;
4626 	int i, j, err;
4627 
4628 	sna_output->props = calloc(sna_output->num_props,
4629 				   sizeof(struct sna_property));
4630 	if (!sna_output->props)
4631 		return;
4632 
4633 	for (i = 0; i < sna_output->num_props; i++) {
4634 		struct sna_property *p = &sna_output->props[i];
4635 
4636 		p->kprop = drmModeGetProperty(sna->kgem.fd,
4637 					      sna_output->prop_ids[i]);
4638 		if (sna_property_ignore(p->kprop)) {
4639 			drmModeFreeProperty(p->kprop);
4640 			p->kprop = NULL;
4641 			continue;
4642 		}
4643 
4644 		if (p->kprop->flags & DRM_MODE_PROP_RANGE) {
4645 			p->num_atoms = 1;
4646 			p->atoms = calloc(p->num_atoms, sizeof(Atom));
4647 			if (!p->atoms)
4648 				continue;
4649 
4650 			sna_output_create_ranged_atom(output, &p->atoms[0],
4651 						      p->kprop->name,
4652 						      p->kprop->values[0],
4653 						      p->kprop->values[1],
4654 						      sna_output->prop_values[i],
4655 						      p->kprop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE);
4656 
4657 		} else if (p->kprop->flags & DRM_MODE_PROP_ENUM) {
4658 			p->num_atoms = p->kprop->count_enums + 1;
4659 			p->atoms = calloc(p->num_atoms, sizeof(Atom));
4660 			if (!p->atoms)
4661 				continue;
4662 
4663 			p->atoms[0] = MakeAtom(p->kprop->name, strlen(p->kprop->name), TRUE);
4664 			for (j = 1; j <= p->kprop->count_enums; j++) {
4665 				struct drm_mode_property_enum *e = &p->kprop->enums[j-1];
4666 				p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE);
4667 			}
4668 
4669 			err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
4670 							FALSE, FALSE,
4671 							p->kprop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
4672 							p->num_atoms - 1, (INT32 *)&p->atoms[1]);
4673 			if (err != 0) {
4674 				xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
4675 					   "RRConfigureOutputProperty error, %d\n", err);
4676 			}
4677 
4678 			for (j = 0; j < p->kprop->count_enums; j++)
4679 				if (p->kprop->enums[j].value == sna_output->prop_values[i])
4680 					break;
4681 			/* there's always a matching value */
4682 			err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
4683 						     XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1],
4684 						     FALSE, FALSE);
4685 			if (err != 0) {
4686 				xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
4687 					   "RRChangeOutputProperty error, %d\n", err);
4688 			}
4689 		}
4690 	}
4691 
4692 	if (sna_output->backlight.iface) {
4693 		/* Set up the backlight property, which takes effect
4694 		 * immediately and accepts values only within the
4695 		 * backlight_range.
4696 		 */
4697 		sna_output_create_ranged_atom(output, &backlight_atom,
4698 					      BACKLIGHT_NAME, 0,
4699 					      sna_output->backlight.max,
4700 					      sna_output->backlight_active_level,
4701 					      FALSE);
4702 		sna_output_create_ranged_atom(output,
4703 					      &backlight_deprecated_atom,
4704 					      BACKLIGHT_DEPRECATED_NAME, 0,
4705 					      sna_output->backlight.max,
4706 					      sna_output->backlight_active_level,
4707 					      FALSE);
4708 	}
4709 }
4710 
4711 static Bool
sna_output_set_property(xf86OutputPtr output,Atom property,RRPropertyValuePtr value)4712 sna_output_set_property(xf86OutputPtr output, Atom property,
4713 			RRPropertyValuePtr value)
4714 {
4715 	struct sna *sna = to_sna(output->scrn);
4716 	struct sna_output *sna_output = output->driver_private;
4717 	int i;
4718 
4719 	if (property == backlight_atom || property == backlight_deprecated_atom) {
4720 		INT32 val;
4721 		int ret = 0;
4722 
4723 		if (value->type != XA_INTEGER || value->format != 32 ||
4724 		    value->size != 1)
4725 		{
4726 			return FALSE;
4727 		}
4728 
4729 		val = *(INT32 *)value->data;
4730 		DBG(("%s: setting backlight to %d (max=%d)\n",
4731 		     __FUNCTION__, (int)val, sna_output->backlight.max));
4732 		if (val < 0 || val > sna_output->backlight.max)
4733 			return FALSE;
4734 
4735 		sna_output->backlight_active_level = val;
4736 		if (sna_output->dpms_mode == DPMSModeOn)
4737 			ret = sna_output_backlight_set(sna_output, val);
4738 		return ret == 0;
4739 	}
4740 
4741 	if (!sna_output->id)
4742 		return TRUE;
4743 
4744 	for (i = 0; i < sna_output->num_props; i++) {
4745 		struct sna_property *p = &sna_output->props[i];
4746 
4747 		if (p->atoms == NULL || p->atoms[0] != property)
4748 			continue;
4749 
4750 		if (p->kprop->flags & DRM_MODE_PROP_RANGE) {
4751 			uint32_t val;
4752 
4753 			if (value->type != XA_INTEGER || value->format != 32 ||
4754 			    value->size != 1)
4755 				return FALSE;
4756 
4757 			val = *(uint32_t *)value->data;
4758 			drmModeConnectorSetProperty(sna->kgem.fd, sna_output->id,
4759 						    p->kprop->prop_id, (uint64_t)val);
4760 			return TRUE;
4761 		} else if (p->kprop->flags & DRM_MODE_PROP_ENUM) {
4762 			Atom atom;
4763 			const char *name;
4764 			int j;
4765 
4766 			if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
4767 				return FALSE;
4768 
4769 			memcpy(&atom, value->data, 4);
4770 			name = NameForAtom(atom);
4771 			if (name == NULL)
4772 				return FALSE;
4773 
4774 			/* search for matching name string, then set its value down */
4775 			for (j = 0; j < p->kprop->count_enums; j++) {
4776 				if (!strcmp(p->kprop->enums[j].name, name)) {
4777 					drmModeConnectorSetProperty(sna->kgem.fd, sna_output->id,
4778 								    p->kprop->prop_id, p->kprop->enums[j].value);
4779 					return TRUE;
4780 				}
4781 			}
4782 			return FALSE;
4783 		}
4784 	}
4785 
4786 	/* We didn't recognise this property, just report success in order
4787 	 * to allow the set to continue, otherwise we break setting of
4788 	 * common properties like EDID.
4789 	 */
4790 	return TRUE;
4791 }
4792 
4793 static Bool
sna_output_get_property(xf86OutputPtr output,Atom property)4794 sna_output_get_property(xf86OutputPtr output, Atom property)
4795 {
4796 	struct sna_output *sna_output = output->driver_private;
4797 	int err, i, j;
4798 
4799 	if (property == backlight_atom || property == backlight_deprecated_atom) {
4800 		INT32 val;
4801 
4802 		if (!sna_output->backlight.iface)
4803 			return FALSE;
4804 
4805 		if (sna_output->dpms_mode == DPMSModeOn) {
4806 			val = sna_output_backlight_get(output);
4807 			if (val < 0)
4808 				return FALSE;
4809 			DBG(("%s(%s): output on, reporting actual backlight value [%d]\n",
4810 			     __FUNCTION__, output->name, val));
4811 		} else {
4812 			val = sna_output->backlight_active_level;
4813 			DBG(("%s(%s): output off, reporting cached backlight value [%d]\n",
4814 			     __FUNCTION__, output->name, val));
4815 		}
4816 
4817 		err = RRChangeOutputProperty(output->randr_output, property,
4818 					     XA_INTEGER, 32, PropModeReplace, 1, &val,
4819 					     FALSE, FALSE);
4820 		if (err != 0) {
4821 			xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
4822 				   "RRChangeOutputProperty error, %d\n", err);
4823 			return FALSE;
4824 		}
4825 
4826 		return TRUE;
4827 	}
4828 
4829 	for (i = 0; i < sna_output->num_props; i++) {
4830 		struct sna_property *p = &sna_output->props[i];
4831 
4832 		if (p->atoms == NULL || p->atoms[0] != property)
4833 			continue;
4834 
4835 		if (sna_output->update_properties && output->scrn->vtSema)
4836 			update_properties(to_sna(output->scrn), sna_output);
4837 
4838 		err = 0;
4839 		if (p->kprop->flags & DRM_MODE_PROP_RANGE) {
4840 			err = RRChangeOutputProperty(output->randr_output,
4841 						     property, XA_INTEGER, 32,
4842 						     PropModeReplace, 1,
4843 						     &sna_output->prop_values[i],
4844 						     FALSE, FALSE);
4845 		} else if (p->kprop->flags & DRM_MODE_PROP_ENUM) {
4846 			for (j = 0; j < p->kprop->count_enums; j++) {
4847 				if (p->kprop->enums[j].value == sna_output->prop_values[i])
4848 					break;
4849 			}
4850 			err = RRChangeOutputProperty(output->randr_output,
4851 						     property, XA_ATOM, 32,
4852 						     PropModeReplace, 1,
4853 						     &p->atoms[j+1],
4854 						     FALSE, FALSE);
4855 		}
4856 
4857 		if (err != 0)
4858 			xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
4859 				   "RRChangeOutputProperty error, %d\n", err);
4860 		return TRUE;
4861 	}
4862 
4863 	return FALSE;
4864 }
4865 
4866 static const xf86OutputFuncsRec sna_output_funcs = {
4867 	.create_resources = sna_output_create_resources,
4868 #ifdef RANDR_12_INTERFACE
4869 	.set_property = sna_output_set_property,
4870 	.get_property = sna_output_get_property,
4871 #endif
4872 	.dpms = sna_output_dpms,
4873 	.detect = sna_output_detect,
4874 	.mode_valid = sna_output_mode_valid,
4875 
4876 	.get_modes = sna_output_get_modes,
4877 	.destroy = sna_output_destroy
4878 };
4879 
4880 static const int subpixel_conv_table[] = {
4881 	SubPixelUnknown,
4882 	SubPixelHorizontalRGB,
4883 	SubPixelHorizontalBGR,
4884 	SubPixelVerticalRGB,
4885 	SubPixelVerticalBGR,
4886 	SubPixelNone
4887 };
4888 
4889 static const char * const output_names[] = {
4890 	/* DRM_MODE_CONNECTOR_Unknown */	"None",
4891 	/* DRM_MODE_CONNECTOR_VGA */		"VGA",
4892 	/* DRM_MODE_CONNECTOR_DVII */		"DVI",
4893 	/* DRM_MODE_CONNECTOR_DVID */		"DVI",
4894 	/* DRM_MODE_CONNECTOR_DVIA */		"DVI",
4895 	/* DRM_MODE_CONNECTOR_Composite */	"Composite",
4896 	/* DRM_MODE_CONNECTOR_SVIDEO */		"TV",
4897 	/* DRM_MODE_CONNECTOR_LVDS */		"LVDS",
4898 	/* DRM_MODE_CONNECTOR_Component */	"CTV",
4899 	/* DRM_MODE_CONNECTOR_9PinDIN */	"DIN",
4900 	/* DRM_MODE_CONNECTOR_DisplayPort */	"DP",
4901 	/* DRM_MODE_CONNECTOR_HDMIA */		"HDMI",
4902 	/* DRM_MODE_CONNECTOR_HDMIB */		"HDMI",
4903 	/* DRM_MODE_CONNECTOR_TV */		"TV",
4904 	/* DRM_MODE_CONNECTOR_eDP */		"eDP",
4905 	/* DRM_MODE_CONNECTOR_VIRTUAL */	"Virtual",
4906 	/* DRM_MODE_CONNECTOR_DSI */		"DSI",
4907 	/* DRM_MODE_CONNECTOR_DPI */		"DPI"
4908 };
4909 
4910 static bool
output_ignored(ScrnInfoPtr scrn,const char * name)4911 output_ignored(ScrnInfoPtr scrn, const char *name)
4912 {
4913 	char monitor_name[64];
4914 	const char *monitor;
4915 	XF86ConfMonitorPtr conf;
4916 
4917 	snprintf(monitor_name, sizeof(monitor_name), "monitor-%s", name);
4918 	monitor = xf86findOptionValue(scrn->options, monitor_name);
4919 	if (!monitor)
4920 		monitor = name;
4921 
4922 	conf = xf86findMonitor(monitor,
4923 			       xf86configptr->conf_monitor_lst);
4924 	if (conf == NULL && XF86_CRTC_CONFIG_PTR(scrn)->num_output == 0)
4925 		conf = xf86findMonitor(scrn->monitor->id,
4926 				       xf86configptr->conf_monitor_lst);
4927 	if (conf == NULL)
4928 		return false;
4929 
4930 	return xf86CheckBoolOption(conf->mon_option_lst, "Ignore", 0);
4931 }
4932 
4933 static bool
gather_encoders(struct sna * sna,uint32_t id,int count,struct drm_mode_get_encoder * out)4934 gather_encoders(struct sna *sna, uint32_t id, int count,
4935 		struct drm_mode_get_encoder *out)
4936 {
4937 	union compat_mode_get_connector compat_conn;
4938 	struct drm_mode_modeinfo dummy;
4939 	struct drm_mode_get_encoder enc;
4940 	uint32_t *ids = NULL;
4941 
4942 	DBG(("%s(%d): expected count=%d\n", __FUNCTION__, id, count));
4943 
4944 	VG_CLEAR(compat_conn);
4945 	VG_CLEAR(enc);
4946 	memset(out, 0, sizeof(*out));
4947 
4948 	do {
4949 		uint32_t *nids;
4950 
4951 		nids = realloc(ids, sizeof(*ids) * count);
4952 		if (nids == NULL) {
4953 			free(ids);
4954 			return false;
4955 		}
4956 		ids = nids;
4957 
4958 		compat_conn.conn.connector_id = id;
4959 		compat_conn.conn.count_props = 0;
4960 		compat_conn.conn.count_modes = 1; /* skip detect */
4961 		compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
4962 		compat_conn.conn.count_encoders = count;
4963 		compat_conn.conn.encoders_ptr = (uintptr_t)ids;
4964 
4965 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
4966 			DBG(("%s: GETCONNECTOR[%d] failed, ret=%d\n", __FUNCTION__, id, errno));
4967 			compat_conn.conn.count_encoders = count = 0;
4968 		}
4969 
4970 		VG(VALGRIND_MAKE_MEM_DEFINED(ids, sizeof(uint32_t)*compat_conn.conn.count_encoders));
4971 		if (count == compat_conn.conn.count_encoders)
4972 			break;
4973 
4974 		count = compat_conn.conn.count_encoders;
4975 	} while (1);
4976 
4977 	DBG(("%s(%d): gathering %d encoders\n", __FUNCTION__, id, count));
4978 	for (count = 0; count < compat_conn.conn.count_encoders; count++) {
4979 		enc.encoder_id = ids[count];
4980 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
4981 			DBG(("%s: GETENCODER[%d] failed, ret=%d\n", __FUNCTION__, ids[count], errno));
4982 			count = 0;
4983 			break;
4984 		}
4985 		DBG(("%s(%d): encoder=%d, possible_crtcs=%x, possible_clones=%x\n",
4986 		     __FUNCTION__, id, enc.encoder_id, enc.possible_crtcs, enc.possible_clones));
4987 		out->possible_crtcs |= enc.possible_crtcs;
4988 		out->possible_clones |= enc.possible_clones;
4989 
4990 		for (id = 0; id < sna->mode.num_real_encoder; id++) {
4991 			if (enc.encoder_id == sna->mode.encoders[id]) {
4992 				out->crtc_id |= 1 << id;
4993 				break;
4994 			}
4995 		}
4996 	}
4997 
4998 	free(ids);
4999 	return count > 0;
5000 }
5001 
5002 /* We need to map from kms encoder based possible_clones mask to X output based
5003  * possible clones masking. Note that for SDVO and on Haswell with DP/HDMI we
5004  * can have more than one output hanging off the same encoder.
5005  */
5006 static void
sna_mode_compute_possible_outputs(struct sna * sna)5007 sna_mode_compute_possible_outputs(struct sna *sna)
5008 {
5009 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5010 	int encoder_mask[32];
5011 	int i, j;
5012 
5013 	assert(sna->mode.num_real_output < 32);
5014 	assert(sna->mode.num_real_crtc < 32);
5015 
5016 	for (i = 0; i < sna->mode.num_real_output; i++) {
5017 		xf86OutputPtr output = config->output[i];
5018 		struct sna_output *sna_output = to_sna_output(output);
5019 
5020 		assert(sna_output);
5021 
5022 		if (sna_output->id) {
5023 			output->possible_clones = sna_output->possible_encoders;
5024 			encoder_mask[i] = sna_output->attached_encoders;
5025 		} else {
5026 			output->possible_clones = 0;
5027 			encoder_mask[i] = 0;
5028 		}
5029 	}
5030 
5031 	/* Convert from encoder numbering to output numbering */
5032 	for (i = 0; i < sna->mode.num_real_output; i++) {
5033 		xf86OutputPtr output = config->output[i];
5034 		unsigned clones;
5035 
5036 		if (output->possible_clones == 0)
5037 			continue;
5038 
5039 		clones = 0;
5040 		for (j = 0; j < sna->mode.num_real_output; j++)
5041 			if (i != j && output->possible_clones & encoder_mask[j])
5042 				clones |= 1 << j;
5043 		output->possible_clones = clones;
5044 
5045 		DBG(("%s: updated output '%s' %d [%d] (possible crtc:%x, possible clones:%x)\n",
5046 		     __FUNCTION__, output->name, i, to_connector_id(output),
5047 		     (uint32_t)output->possible_crtcs,
5048 		     (uint32_t)output->possible_clones));
5049 	}
5050 }
5051 
name_from_path(struct sna * sna,struct sna_output * sna_output,char * name)5052 static int name_from_path(struct sna *sna,
5053 			  struct sna_output *sna_output,
5054 			  char *name)
5055 {
5056 	struct drm_mode_get_blob blob;
5057 	char *path;
5058 	int id;
5059 
5060 	id = find_property(sna, sna_output, "PATH");
5061 	DBG(("%s: found? PATH=%d\n", __FUNCTION__, id));
5062 	if (id == -1)
5063 		return 0;
5064 
5065 	VG_CLEAR(blob);
5066 	blob.blob_id = sna_output->prop_values[id];
5067 	blob.length = 0;
5068 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
5069 		return 0;
5070 
5071 	do {
5072 		id = blob.length;
5073 		path = alloca(id + 1);
5074 		blob.data = (uintptr_t)path;
5075 		VG(memset(path, 0, id));
5076 		DBG(("%s: reading %d bytes for path blob\n", __FUNCTION__, id));
5077 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
5078 			return 0;
5079 	} while (id != blob.length);
5080 
5081 	path[blob.length] = '\0'; /* paranoia */
5082 	DBG(("%s: PATH='%s'\n", __FUNCTION__, path));
5083 
5084 	/* we only handle MST paths for now */
5085 	if (strncmp(path, "mst:", 4) == 0) {
5086 		xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5087 		char tmp[5], *c;
5088 		int n;
5089 
5090 		c = strchr(path + 4, '-');
5091 		if (c == NULL)
5092 			return 0;
5093 
5094 		id = c - (path + 4);
5095 		if (id + 1> 5)
5096 			return 0;
5097 
5098 		memcpy(tmp, path + 4, id);
5099 		tmp[id] = '\0';
5100 		id = strtoul(tmp, NULL, 0);
5101 
5102 		for (n = 0; n < sna->mode.num_real_output; n++) {
5103 			if (to_sna_output(config->output[n])->id == id)
5104 				return snprintf(name, 32, "%s-%s",
5105 						config->output[n]->name, c + 1);
5106 		}
5107 	}
5108 
5109 	return 0;
5110 }
5111 
fake_edid_name(xf86OutputPtr output)5112 static char *fake_edid_name(xf86OutputPtr output)
5113 {
5114 	struct sna *sna = to_sna(output->scrn);
5115 	const char *str, *colon;
5116 
5117 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,99,901,0)
5118 	str = xf86GetOptValString(sna->Options, OPTION_EDID);
5119 #else
5120 	str = NULL;
5121 #endif
5122 	if (str == NULL)
5123 		return NULL;
5124 
5125 	do {
5126 		colon = strchr(str, ':');
5127 		if (colon == NULL)
5128 			return NULL;
5129 
5130 		if (strncmp(str, output->name, colon-str) == 0 &&
5131 		    output->name[colon-str] == '\0') {
5132 			char *path;
5133 			int len;
5134 
5135 			str = colon + 1;
5136 			colon = strchr(str, ',');
5137 			if (colon)
5138 				len = colon - str;
5139 			else
5140 				len = strlen(str);
5141 
5142 			path = malloc(len + 1);
5143 			if (path == NULL)
5144 				return NULL;
5145 
5146 			memcpy(path, str, len);
5147 			path[len] = '\0';
5148 			return path;
5149 		}
5150 
5151 		str = strchr(colon + 1, ',');
5152 		if (str == NULL)
5153 			return NULL;
5154 
5155 		str++;
5156 	} while (1);
5157 }
5158 
5159 static void
sna_output_load_fake_edid(xf86OutputPtr output)5160 sna_output_load_fake_edid(xf86OutputPtr output)
5161 {
5162 	struct sna_output *sna_output = output->driver_private;
5163 	const char *filename;
5164 	FILE *file;
5165 	void *raw;
5166 	int size;
5167 
5168 	filename = fake_edid_name(output);
5169 	if (filename == NULL)
5170 		return;
5171 
5172 	file = fopen(filename, "rb");
5173 	if (file == NULL)
5174 		goto err;
5175 
5176 	fseek(file, 0, SEEK_END);
5177 	size = ftell(file);
5178 	if (size % 128) {
5179 		fclose(file);
5180 		goto err;
5181 	}
5182 
5183 	raw = malloc(size);
5184 	if (raw == NULL) {
5185 		fclose(file);
5186 		free(raw);
5187 		goto err;
5188 	}
5189 
5190 	fseek(file, 0, SEEK_SET);
5191 	if (fread(raw, size, 1, file) != 1) {
5192 		fclose(file);
5193 		free(raw);
5194 		goto err;
5195 	}
5196 	fclose(file);
5197 
5198 	sna_output->fake_edid_raw = raw;
5199 
5200 	xf86DrvMsg(output->scrn->scrnIndex, X_CONFIG,
5201 		   "Loading EDID from \"%s\" for output %s\n",
5202 		   filename, output->name);
5203 	return;
5204 
5205 err:
5206 	xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
5207 		   "Could not read EDID file \"%s\" for output %s\n",
5208 		   filename, output->name);
5209 }
5210 
5211 static int
sna_output_add(struct sna * sna,unsigned id,unsigned serial)5212 sna_output_add(struct sna *sna, unsigned id, unsigned serial)
5213 {
5214 	ScrnInfoPtr scrn = sna->scrn;
5215 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
5216 	union compat_mode_get_connector compat_conn;
5217 	struct drm_mode_get_encoder enc;
5218 	struct drm_mode_modeinfo dummy;
5219 	struct sna_output *sna_output;
5220 	xf86OutputPtr *outputs, output;
5221 	unsigned possible_encoders, attached_encoders, possible_crtcs;
5222 	const char *output_name;
5223 	char name[32];
5224 	int path, len, i;
5225 
5226 	DBG(("%s(%d): serial=%d\n", __FUNCTION__, id, serial));
5227 
5228 	COMPILE_TIME_ASSERT(sizeof(struct drm_mode_get_connector) <= sizeof(compat_conn.pad));
5229 
5230 	VG_CLEAR(compat_conn);
5231 	memset(&enc, 0, sizeof(enc));
5232 
5233 	compat_conn.conn.connector_id = id;
5234 	compat_conn.conn.count_props = 0;
5235 	compat_conn.conn.count_modes = 1; /* skip detect */
5236 	compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
5237 	compat_conn.conn.count_encoders = 1;
5238 	compat_conn.conn.encoders_ptr = (uintptr_t)&enc.encoder_id;
5239 
5240 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
5241 		DBG(("%s: GETCONNECTOR[%d] failed, ret=%d\n", __FUNCTION__, id, errno));
5242 		return -1;
5243 	}
5244 	assert(compat_conn.conn.connector_id == id);
5245 	DBG(("%s(%d): has %d associated encoders\n", __FUNCTION__, id, compat_conn.conn.count_encoders));
5246 
5247 	if (compat_conn.conn.connector_type < ARRAY_SIZE(output_names))
5248 		output_name = output_names[compat_conn.conn.connector_type];
5249 	else
5250 		output_name = "UNKNOWN";
5251 	len = snprintf(name, 32, "%s-%d", output_name, compat_conn.conn.connector_type_id);
5252 	if (output_ignored(scrn, name))
5253 		return 0;
5254 
5255 	if (enc.encoder_id) {
5256 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
5257 			DBG(("%s: GETENCODER[%d] failed, ret=%d\n", __FUNCTION__, enc.encoder_id, errno));
5258 			return 0;
5259 		}
5260 
5261 		possible_encoders = enc.possible_clones;
5262 		attached_encoders = 0;
5263 		for (i = 0; i < sna->mode.num_real_encoder; i++) {
5264 			if (enc.encoder_id == sna->mode.encoders[i]) {
5265 				attached_encoders = 1 << i;
5266 				break;
5267 			}
5268 		}
5269 
5270 		if (attached_encoders == 0) {
5271 			DBG(("%s: failed to find attached encoder\n", __FUNCTION__));
5272 			return 0;
5273 		}
5274 
5275 		possible_crtcs = enc.possible_crtcs;
5276 		assert(enc.encoder_id == compat_conn.conn.encoder_id || compat_conn.conn.encoder_id == 0);
5277 	} else {
5278 		DBG(("%s: unexpected number [%d] of encoders attached\n",
5279 		     __FUNCTION__, compat_conn.conn.count_encoders));
5280 		if (!gather_encoders(sna, id, compat_conn.conn.count_encoders, &enc)) {
5281 			DBG(("%s: gather encoders failed\n", __FUNCTION__));
5282 			return 0;
5283 		}
5284 		possible_encoders = enc.possible_clones;
5285 		attached_encoders = enc.crtc_id;
5286 		possible_crtcs = enc.possible_crtcs;
5287 
5288 		memset(&enc, 0, sizeof(enc));
5289 		enc.encoder_id = compat_conn.conn.encoder_id;
5290 		(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc);
5291 	}
5292 
5293 	if (is_zaphod(scrn)) {
5294 		unsigned zaphod_crtcs;
5295 
5296 		if (!sna_zaphod_match(sna, name)) {
5297 			DBG(("%s: zaphod mismatch, want %s, have %s\n",
5298 			     __FUNCTION__,
5299 			     xf86GetOptValString(sna->Options, OPTION_ZAPHOD) ?: "???",
5300 			     name));
5301 			return 0;
5302 		}
5303 
5304 		zaphod_crtcs = get_zaphod_crtcs(sna);
5305 		possible_crtcs &= zaphod_crtcs;
5306 		if (possible_crtcs == 0) {
5307 			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
5308 				   "%s is an invalid output for screen %d\n",
5309 				   name, scrn->confScreen->device->screen);
5310 			return -1;
5311 		}
5312 
5313 		possible_crtcs >>= ffs(zaphod_crtcs) - 1;
5314 	}
5315 
5316 	sna_output = calloc(sizeof(struct sna_output), 1);
5317 	if (!sna_output)
5318 		return -1;
5319 
5320 	sna_output->connector_type = compat_conn.conn.connector_type;
5321 	sna_output->connector_type_id = compat_conn.conn.connector_type_id;
5322 	sna_output->num_props = compat_conn.conn.count_props;
5323 	sna_output->prop_ids = malloc(sizeof(uint32_t)*compat_conn.conn.count_props);
5324 	sna_output->prop_values = malloc(sizeof(uint64_t)*compat_conn.conn.count_props);
5325 	if (sna_output->prop_ids == NULL || sna_output->prop_values == NULL) {
5326 		free(sna_output->prop_ids);
5327 		free(sna_output->prop_values);
5328 		free(sna_output);
5329 		return -1;
5330 	}
5331 
5332 	compat_conn.conn.count_encoders = 0;
5333 
5334 	compat_conn.conn.count_modes = 1;
5335 	compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
5336 
5337 	compat_conn.conn.count_props = sna_output->num_props;
5338 	compat_conn.conn.props_ptr = (uintptr_t)sna_output->prop_ids;
5339 	compat_conn.conn.prop_values_ptr = (uintptr_t)sna_output->prop_values;
5340 
5341 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
5342 		DBG(("%s: second! GETCONNECTOR failed, ret=%d\n", __FUNCTION__, errno));
5343 		goto cleanup;
5344 	}
5345 	assert(compat_conn.conn.connector_id == id);
5346 
5347 	/* statically constructed property list */
5348 	assert(sna_output->num_props == compat_conn.conn.count_props);
5349 	VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_ids, sizeof(uint32_t)*sna_output->num_props));
5350 	VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_values, sizeof(uint64_t)*sna_output->num_props));
5351 
5352 	/* Construct name from topology, and recheck if output is acceptable */
5353 	path = name_from_path(sna, sna_output, name);
5354 	if (path) {
5355 		if (output_ignored(scrn, name)) {
5356 			len = 0;
5357 			goto skip;
5358 		}
5359 
5360 		if (is_zaphod(scrn) && !sna_zaphod_match(sna, name)) {
5361 			DBG(("%s: zaphod mismatch, want %s, have %s\n",
5362 			     __FUNCTION__,
5363 			     xf86GetOptValString(sna->Options, OPTION_ZAPHOD) ?: "???",
5364 			     name));
5365 			len = 0;
5366 			goto skip;
5367 		}
5368 
5369 		len = path;
5370 	}
5371 
5372 	/* Check if we are dynamically reattaching an old connector */
5373 	if (serial) {
5374 		for (i = 0; i < sna->mode.num_real_output; i++) {
5375 			output = config->output[i];
5376 			if (strcmp(output->name, name) == 0) {
5377 				assert(output->scrn == scrn);
5378 				assert(output->funcs == &sna_output_funcs);
5379 
5380 				/*
5381 				 * If the old output is still in use, tell
5382 				 * the kernel to switch it off so we can
5383 				 * move its resources over to the new id.
5384 				 */
5385 				if (output->crtc) {
5386 					struct drm_mode_crtc arg = {
5387 						.crtc_id = __sna_crtc_id(to_sna_crtc(output->crtc)),
5388 					};
5389 					drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
5390 					output->crtc = NULL;
5391 				}
5392 
5393 				sna_output_destroy(output);
5394 				goto reset;
5395 			}
5396 		}
5397 	}
5398 
5399 	output = calloc(1, sizeof(*output) + len + 1);
5400 	if (!output)
5401 		goto cleanup;
5402 
5403 	outputs = realloc(config->output, (config->num_output + 1) * sizeof(output));
5404 	if (outputs == NULL) {
5405 		free(output);
5406 		goto cleanup;
5407 	}
5408 
5409 	output->scrn = scrn;
5410 	output->funcs = &sna_output_funcs;
5411 	output->name = (char *)(output + 1);
5412 	memcpy(output->name, name, len + 1);
5413 
5414 	output->use_screen_monitor = config->num_output != 0;
5415 	xf86OutputUseScreenMonitor(output, !output->use_screen_monitor);
5416 	assert(output->options);
5417 
5418 	DBG(("%s: inserting output #%d of %d\n", __FUNCTION__, sna->mode.num_real_output, config->num_output));
5419 	for (i = config->num_output; i > sna->mode.num_real_output; i--) {
5420 		outputs[i] = outputs[i-1];
5421 		assert(outputs[i]->driver_private == NULL);
5422 		outputs[i]->possible_clones <<= 1;
5423 	}
5424 
5425 	if (xf86ReturnOptValBool(output->options, OPTION_PRIMARY, FALSE)) {
5426 		memmove(outputs + 1, outputs, sizeof(output)*config->num_output);
5427 		outputs[0] = output;
5428 	} else
5429 		outputs[i] = output;
5430 	sna->mode.num_real_output++;
5431 	config->num_output++;
5432 	config->output = outputs;
5433 
5434 reset:
5435 	sna_output->id = compat_conn.conn.connector_id;
5436 	sna_output->is_panel = is_panel(compat_conn.conn.connector_type);
5437 	sna_output->edid_idx = find_property(sna, sna_output, "EDID");
5438 	sna_output->link_status_idx =
5439 		find_property(sna, sna_output, "link-status");
5440 	if (find_property(sna, sna_output, "scaling mode") != -1)
5441 		sna_output->add_default_modes =
5442 			xf86ReturnOptValBool(output->options, OPTION_DEFAULT_MODES, TRUE);
5443 
5444 	i = find_property(sna, sna_output, "DPMS");
5445 	if (i != -1) {
5446 		sna_output->dpms_id = sna_output->prop_ids[i];
5447 		sna_output->dpms_mode = sna_output->prop_values[i];
5448 		DBG(("%s: found 'DPMS' (idx=%d, id=%d), initial value=%d\n",
5449 		     __FUNCTION__, i, sna_output->dpms_id, sna_output->dpms_mode));
5450 	} else
5451 		sna_output->dpms_mode = DPMSModeOff;
5452 
5453 	sna_output->possible_encoders = possible_encoders;
5454 	sna_output->attached_encoders = attached_encoders;
5455 
5456 	output->mm_width = compat_conn.conn.mm_width;
5457 	output->mm_height = compat_conn.conn.mm_height;
5458 
5459 	if (compat_conn.conn.subpixel >= ARRAY_SIZE(subpixel_conv_table))
5460 		compat_conn.conn.subpixel = 0;
5461 	output->subpixel_order = subpixel_conv_table[compat_conn.conn.subpixel];
5462 	output->driver_private = sna_output;
5463 	sna_output->base = output;
5464 
5465 	backlight_init(&sna_output->backlight);
5466 	sna_output_backlight_init(output);
5467 
5468 	output->possible_crtcs = possible_crtcs & count_to_mask(sna->mode.num_real_crtc);
5469 	output->interlaceAllowed = TRUE;
5470 
5471 	sna_output_load_fake_edid(output);
5472 
5473 	if (serial) {
5474 		if (output->randr_output == NULL) {
5475 			output->randr_output = RROutputCreate(xf86ScrnToScreen(scrn), name, len, output);
5476 			if (output->randr_output == NULL)
5477 				goto cleanup;
5478 		}
5479 
5480 		RROutputChanged(output->randr_output, TRUE);
5481 		sna_output_create_resources(output);
5482 		RRPostPendingProperties(output->randr_output);
5483 
5484 		sna_output->serial = serial;
5485 	} else {
5486 		/* stash the active CRTC id for our probe function */
5487 		if (compat_conn.conn.connection != DRM_MODE_DISCONNECTED)
5488 			output->crtc = (void *)(uintptr_t)enc.crtc_id;
5489 	}
5490 
5491 	DBG(("%s: created output '%s' %d, encoder=%d (possible crtc:%x, attached encoders:%x, possible clones:%x), serial=%d, edid=%d, dpms=%d, crtc=%lu\n",
5492 	     __FUNCTION__, name, id, enc.encoder_id,
5493 	     (uint32_t)output->possible_crtcs,
5494 	     sna_output->attached_encoders,
5495 	     sna_output->possible_encoders,
5496 	     serial, sna_output->edid_idx, sna_output->dpms_id,
5497 	     (unsigned long)(uintptr_t)output->crtc));
5498 	assert(sna_output->id == id);
5499 
5500 	xf86DrvMsg(scrn->scrnIndex, X_INFO,
5501 		   "Enabled output %s\n",
5502 		   output->name);
5503 	return 1;
5504 
5505 cleanup:
5506 	len = -1;
5507 skip:
5508 	free(sna_output->prop_ids);
5509 	free(sna_output->prop_values);
5510 	free(sna_output);
5511 	return len;
5512 }
5513 
output_rank(const void * A,const void * B)5514 static int output_rank(const void *A, const void *B)
5515 {
5516 	const xf86OutputPtr *a = A;
5517 	const xf86OutputPtr *b = B;
5518 	struct sna_output *sa = to_sna_output(*a);
5519 	struct sna_output *sb = to_sna_output(*b);
5520 
5521 	if (sa->is_panel != sb->is_panel)
5522 		return sb->is_panel - sa->is_panel;
5523 
5524 	return strcmp((*a)->name, (*b)->name);
5525 }
5526 
sort_config_outputs(struct sna * sna)5527 static void sort_config_outputs(struct sna *sna)
5528 {
5529 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5530 	qsort(config->output, sna->mode.num_real_output, sizeof(*config->output), output_rank);
5531 	config->compat_output = 0; /* make sure it is a sane value */
5532 	sna_mode_compute_possible_outputs(sna);
5533 }
5534 
sort_randr_outputs(struct sna * sna,ScreenPtr screen)5535 static void sort_randr_outputs(struct sna *sna, ScreenPtr screen)
5536 {
5537 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5538 	rrScrPriv(screen);
5539 	int i;
5540 
5541 	assert(pScrPriv->numOutputs == config->num_output);
5542 	for (i = 0; i < config->num_output; i++) {
5543 		assert(config->output[i]->randr_output);
5544 		pScrPriv->outputs[i] = config->output[i]->randr_output;
5545 	}
5546 }
5547 
disable_unused_crtc(struct sna * sna)5548 static bool disable_unused_crtc(struct sna *sna)
5549 {
5550 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5551 	bool update = false;
5552 	int o, c;
5553 
5554 	DBG(("%s\n", __FUNCTION__));
5555 
5556 	for (c = 0; c < sna->mode.num_real_crtc; c++) {
5557 		xf86CrtcPtr crtc = config->crtc[c];
5558 
5559 		if (!crtc->enabled) {
5560 			sna_crtc_disable(crtc, false);
5561 			continue;
5562 		}
5563 
5564 		for (o = 0; o < sna->mode.num_real_output; o++) {
5565 			xf86OutputPtr output = config->output[o];
5566 			if (output->crtc == crtc)
5567 				break;
5568 		}
5569 
5570 		if (o == sna->mode.num_real_output) {
5571 			DBG(("%s: CRTC:%d was enabled with no outputs\n",
5572 			     __FUNCTION__, sna_crtc_id(crtc)));
5573 			crtc->enabled = false;
5574 			update = true;
5575 		}
5576 	}
5577 
5578 	if (update) {
5579 		DBG(("%s: disabling unused functions\n", __FUNCTION__));
5580 		xf86DisableUnusedFunctions(sna->scrn);
5581 	}
5582 
5583 	return update;
5584 }
5585 
sna_mode_find_hotplug_connector(struct sna * sna,unsigned id)5586 bool sna_mode_find_hotplug_connector(struct sna *sna, unsigned id)
5587 {
5588 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5589 	int i;
5590 
5591 	for (i = 0; i < sna->mode.num_real_output; i++) {
5592 		struct sna_output *output = to_sna_output(config->output[i]);
5593 		if (output->id == id) {
5594 			output->reprobe = true;
5595 			return true;
5596 		}
5597 	}
5598 
5599 	return false;
5600 }
5601 
5602 static bool
output_retrain_link(struct sna * sna,struct sna_output * output)5603 output_retrain_link(struct sna *sna, struct sna_output *output)
5604 {
5605 	struct sna_crtc *crtc = to_sna_crtc(output->base->crtc);
5606 	int crtc_x = crtc->offset & 0xffff;
5607 	int crtc_y = crtc->offset >> 16;
5608 
5609 	if (!crtc->bo)
5610 		return false;
5611 
5612 	return sna_crtc_flip(sna, crtc, crtc->bo, crtc_x, crtc_y);
5613 }
5614 
5615 static bool
output_check_link(struct sna * sna,struct sna_output * output)5616 output_check_link(struct sna *sna, struct sna_output *output)
5617 {
5618 	uint64_t link_status;
5619 
5620 	if (!output->base->crtc)
5621 		return true;
5622 
5623 	if (output->link_status_idx == -1)
5624 		return true;
5625 
5626 #define LINK_STATUS_GOOD 0
5627 	link_status = output->prop_values[output->link_status_idx];
5628 	DBG(("%s: link_status=%d\n", __FUNCTION__, link_status));
5629 	if (link_status == LINK_STATUS_GOOD)
5630 		return true;
5631 
5632 	/* Perform a modeset as required for "link-status" = BAD */
5633 	if (!output_retrain_link(sna, output))
5634 		return false;
5635 
5636 	/* Query the "link-status" again to confirm the modeset */
5637 	update_properties(sna, output);
5638 
5639 	link_status = output->prop_values[output->link_status_idx];
5640 	DBG(("%s: link_status=%d after modeset\n", __FUNCTION__, link_status));
5641 	return link_status == LINK_STATUS_GOOD;
5642 }
5643 
5644 static bool
output_check_status(struct sna * sna,struct sna_output * output)5645 output_check_status(struct sna *sna, struct sna_output *output)
5646 {
5647 	union compat_mode_get_connector compat_conn;
5648 	struct drm_mode_modeinfo dummy;
5649 	struct drm_mode_get_blob blob;
5650 	xf86OutputStatus status;
5651 	char *edid;
5652 
5653 	VG_CLEAR(compat_conn);
5654 
5655 	compat_conn.conn.connection = -1;
5656 	compat_conn.conn.connector_id = output->id;
5657 	compat_conn.conn.count_modes = 1; /* skip detect */
5658 	compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
5659 	compat_conn.conn.count_encoders = 0;
5660 	compat_conn.conn.props_ptr = (uintptr_t)output->prop_ids;
5661 	compat_conn.conn.prop_values_ptr = (uintptr_t)output->prop_values;
5662 	compat_conn.conn.count_props = output->num_props;
5663 
5664 	if (drmIoctl(sna->kgem.fd,
5665 		     DRM_IOCTL_MODE_GETCONNECTOR,
5666 		     &compat_conn.conn) == 0)
5667 		output->update_properties = false;
5668 
5669 	if (!output_check_link(sna, output))
5670 		return false;
5671 
5672 	if (output->reprobe)
5673 		return false;
5674 
5675 	switch (compat_conn.conn.connection) {
5676 	case DRM_MODE_CONNECTED:
5677 		status = XF86OutputStatusConnected;
5678 		break;
5679 	case DRM_MODE_DISCONNECTED:
5680 		status = XF86OutputStatusDisconnected;
5681 		break;
5682 	default:
5683 	case DRM_MODE_UNKNOWNCONNECTION:
5684 		status = XF86OutputStatusUnknown;
5685 		break;
5686 	}
5687 	if (output->status != status)
5688 		return false;
5689 
5690 	if (status != XF86OutputStatusConnected)
5691 		return true;
5692 
5693 	if (output->num_modes != compat_conn.conn.count_modes)
5694 		return false;
5695 
5696 	if (output->edid_len == 0)
5697 		return false;
5698 
5699 	edid = alloca(output->edid_len);
5700 
5701 	VG_CLEAR(blob);
5702 	blob.blob_id = output->prop_values[output->edid_idx];
5703 	blob.length = output->edid_len;
5704 	blob.data = (uintptr_t)edid;
5705 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
5706 		return false;
5707 
5708 	if (blob.length != output->edid_len)
5709 		return false;
5710 
5711 	return memcmp(edid, output->edid_raw, output->edid_len) == 0;
5712 }
5713 
sna_mode_discover(struct sna * sna,bool tell)5714 void sna_mode_discover(struct sna *sna, bool tell)
5715 {
5716 	ScreenPtr screen = xf86ScrnToScreen(sna->scrn);
5717 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5718 	bool force = sna->flags & SNA_REPROBE;
5719 	struct drm_mode_card_res res;
5720 	uint32_t connectors[32], now;
5721 	unsigned changed = 0;
5722 	unsigned serial;
5723 	int i, j;
5724 
5725 	DBG(("%s()\n", __FUNCTION__));
5726 	sna->flags &= ~SNA_REPROBE;
5727 
5728 	VG_CLEAR(connectors);
5729 
5730 	memset(&res, 0, sizeof(res));
5731 	res.count_connectors = 32;
5732 	res.connector_id_ptr = (uintptr_t)connectors;
5733 
5734 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
5735 		return;
5736 
5737 	DBG(("%s: now %d (was %d) connectors, %d encoders, %d crtc\n", __FUNCTION__,
5738 	     res.count_connectors, sna->mode.num_real_output,
5739 	     res.count_encoders, res.count_crtcs));
5740 	if (res.count_connectors > 32)
5741 		res.count_connectors = 32;
5742 
5743 	assert(sna->mode.num_real_crtc == res.count_crtcs || is_zaphod(sna->scrn));
5744 	assert(sna->mode.max_crtc_width  == res.max_width);
5745 	assert(sna->mode.max_crtc_height == res.max_height);
5746 	assert(sna->mode.num_real_encoder == res.count_encoders);
5747 
5748 	serial = ++sna->mode.serial;
5749 	if (serial == 0)
5750 		serial = ++sna->mode.serial;
5751 
5752 	if (force) {
5753 		changed = 4;
5754 		now = 0;
5755 	} else
5756 		now = GetTimeInMillis();
5757 	for (i = 0; i < res.count_connectors; i++) {
5758 		DBG(("%s: connector[%d] = %d\n", __FUNCTION__, i, connectors[i]));
5759 		for (j = 0; j < sna->mode.num_real_output; j++) {
5760 			xf86OutputPtr output = config->output[j];
5761 			if (to_sna_output(output)->id == connectors[i]) {
5762 				DBG(("%s: found %s (id=%d)\n", __FUNCTION__, output->name, connectors[i]));
5763 				assert(to_sna_output(output)->id);
5764 				to_sna_output(output)->serial = serial;
5765 				break;
5766 			}
5767 		}
5768 		if (j == sna->mode.num_real_output) {
5769 			DBG(("%s: adding id=%d\n", __FUNCTION__, connectors[i]));
5770 			changed |= sna_output_add(sna, connectors[i], serial) > 0;
5771 		}
5772 	}
5773 
5774 	for (i = 0; i < sna->mode.num_real_output; i++) {
5775 		xf86OutputPtr output = config->output[i];
5776 		struct sna_output *sna_output = to_sna_output(output);
5777 
5778 		if (sna_output->id == 0)
5779 			continue;
5780 
5781 		if (sna_output->serial == serial) {
5782 			if (output_check_status(sna, sna_output)) {
5783 				DBG(("%s: output %s (id=%d), retained state\n",
5784 				     __FUNCTION__, output->name, sna_output->id));
5785 				sna_output->last_detect = now;
5786 			} else {
5787 				DBG(("%s: output %s (id=%d), changed state, reprobing\n",
5788 				     __FUNCTION__, output->name, sna_output->id));
5789 				sna_output->hotplug_count++;
5790 				sna_output->last_detect = 0;
5791 				changed |= 4;
5792 			}
5793 			continue;
5794 		}
5795 
5796 		DBG(("%s: removing output %s (id=%d), serial=%u [now %u]\n",
5797 		     __FUNCTION__, output->name, sna_output->id,
5798 		    sna_output->serial, serial));
5799 
5800 		xf86DrvMsg(sna->scrn->scrnIndex, X_INFO,
5801 			   "Disabled output %s\n",
5802 			   output->name);
5803 		sna_output->id = 0;
5804 		sna_output->last_detect = 0;
5805 		output->crtc = NULL;
5806 		RROutputChanged(output->randr_output, TRUE);
5807 		changed |= 2;
5808 	}
5809 
5810 	/* Have the list of available outputs been updated? */
5811 	if (changed & 3) {
5812 		DBG(("%s: outputs changed, broadcasting\n", __FUNCTION__));
5813 
5814 		sna_mode_set_primary(sna);
5815 
5816 		/* Reorder user visible listing */
5817 		sort_config_outputs(sna);
5818 		sort_randr_outputs(sna, screen);
5819 
5820 		if (changed & 2)
5821 			disable_unused_crtc(sna);
5822 
5823 		xf86RandR12TellChanged(screen);
5824 	}
5825 
5826 	/* If anything has changed, refresh the RandR information.
5827 	 * Note this could recurse once from udevless RRGetInfo() probes,
5828 	 * but only once.
5829 	 */
5830 	if (changed && tell)
5831 		RRGetInfo(screen, TRUE);
5832 }
5833 
5834 /* Since we only probe the current mode on startup, we may not have the full
5835  * list of modes available until the user explicitly requests them. Fake a
5836  * hotplug event after a second after starting to fill in any missing modes.
5837  */
sna_mode_coldplug(OsTimerPtr timer,CARD32 now,void * data)5838 CARD32 sna_mode_coldplug(OsTimerPtr timer, CARD32 now, void *data)
5839 {
5840 	struct sna *sna = data;
5841 	ScreenPtr screen = xf86ScrnToScreen(sna->scrn);
5842 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5843 	bool reprobe = false;
5844 	int i;
5845 
5846 	DBG(("%s()\n", __FUNCTION__));
5847 
5848 	for (i = 0; i < sna->mode.num_real_output; i++) {
5849 		xf86OutputPtr output = config->output[i];
5850 		struct sna_output *sna_output = to_sna_output(output);
5851 
5852 		if (sna_output->id == 0)
5853 			continue;
5854 		if (sna_output->last_detect)
5855 			continue;
5856 		if (output->status == XF86OutputStatusDisconnected)
5857 			continue;
5858 
5859 		DBG(("%s: output %s connected, needs reprobe\n",
5860 		     __FUNCTION__, output->name));
5861 		reprobe = true;
5862 	}
5863 
5864 	if (reprobe) {
5865 		RRGetInfo(screen, TRUE);
5866 		RRTellChanged(screen);
5867 	}
5868 	free(timer);
5869 	return 0;
5870 }
5871 
copy_front(struct sna * sna,PixmapPtr old,PixmapPtr new)5872 static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
5873 {
5874 	struct sna_pixmap *old_priv, *new_priv;
5875 
5876 	DBG(("%s\n", __FUNCTION__));
5877 
5878 	if (wedged(sna) || isGPU(sna->scrn))
5879 		return;
5880 
5881 	old_priv = sna_pixmap_force_to_gpu(old, MOVE_READ);
5882 	if (!old_priv)
5883 		return;
5884 
5885 	new_priv = sna_pixmap_force_to_gpu(new, MOVE_WRITE | __MOVE_SCANOUT);
5886 	if (!new_priv)
5887 		return;
5888 
5889 	if (old_priv->clear) {
5890 		bool ok = false;
5891 		if (!wedged(sna))
5892 			ok = sna->render.fill_one(sna, new, new_priv->gpu_bo,
5893 						  old_priv->clear_color,
5894 						  0, 0,
5895 						  new->drawable.width,
5896 						  new->drawable.height,
5897 						  GXcopy);
5898 		if (!ok) {
5899 			void *ptr = kgem_bo_map__gtt(&sna->kgem, new_priv->gpu_bo);
5900 			if (ptr)
5901 				memset(ptr, 0, new_priv->gpu_bo->pitch*new->drawable.height);
5902 		}
5903 		new_priv->clear = true;
5904 		new_priv->clear_color = old_priv->clear_color;
5905 	} else {
5906 		BoxRec box;
5907 		int16_t sx, sy, dx, dy;
5908 
5909 		if (new->drawable.width >= old->drawable.width &&
5910 		    new->drawable.height >= old->drawable.height)
5911 		{
5912 			int nx = (new->drawable.width + old->drawable.width - 1) / old->drawable.width;
5913 			int ny = (new->drawable.height + old->drawable.height - 1) / old->drawable.height;
5914 
5915 			box.x1 = box.y1 = 0;
5916 
5917 			dy = 0;
5918 			for (sy = 0; sy < ny; sy++) {
5919 				box.y2 = old->drawable.height;
5920 				if (box.y2 + dy > new->drawable.height)
5921 					box.y2 = new->drawable.height - dy;
5922 
5923 				dx = 0;
5924 				for (sx = 0; sx < nx; sx++) {
5925 					box.x2 = old->drawable.width;
5926 					if (box.x2 + dx > new->drawable.width)
5927 						box.x2 = new->drawable.width - dx;
5928 
5929 					(void)sna->render.copy_boxes(sna, GXcopy,
5930 								     &old->drawable, old_priv->gpu_bo, 0, 0,
5931 								     &new->drawable, new_priv->gpu_bo, dx, dy,
5932 								     &box, 1, 0);
5933 					dx += old->drawable.width;
5934 				}
5935 				dy += old->drawable.height;
5936 			}
5937 		} else {
5938 			box.x1 = box.y1 = 0;
5939 			box.x2 = min(old->drawable.width, new->drawable.width);
5940 			box.y2 = min(old->drawable.height, new->drawable.height);
5941 
5942 			sx = dx = 0;
5943 			if (box.x2 < old->drawable.width)
5944 				sx = (old->drawable.width - box.x2) / 2;
5945 			if (box.x2 < new->drawable.width)
5946 				dx = (new->drawable.width - box.x2) / 2;
5947 
5948 			sy = dy = 0;
5949 			if (box.y2 < old->drawable.height)
5950 				sy = (old->drawable.height - box.y2) / 2;
5951 			if (box.y2 < new->drawable.height)
5952 				dy = (new->drawable.height - box.y2) / 2;
5953 
5954 			DBG(("%s: copying box (%dx%d) from (%d, %d) to (%d, %d)\n",
5955 			     __FUNCTION__, box.x2, box.y2, sx, sy, dx, dy));
5956 
5957 			if (box.x2 != new->drawable.width || box.y2 != new->drawable.height) {
5958 				bool ok = false;
5959 				if (!wedged(sna))
5960 					ok = sna->render.fill_one(sna, new, new_priv->gpu_bo, 0,
5961 								  0, 0,
5962 								  new->drawable.width,
5963 								  new->drawable.height,
5964 								  GXclear);
5965 				if (!ok) {
5966 					void *ptr = kgem_bo_map__gtt(&sna->kgem, new_priv->gpu_bo);
5967 					if (ptr)
5968 						memset(ptr, 0, new_priv->gpu_bo->pitch*new->drawable.height);
5969 				}
5970 			}
5971 			(void)sna->render.copy_boxes(sna, GXcopy,
5972 						     &old->drawable, old_priv->gpu_bo, sx, sy,
5973 						     &new->drawable, new_priv->gpu_bo, dx, dy,
5974 						     &box, 1, 0);
5975 		}
5976 	}
5977 
5978 	sna_damage_all(&new_priv->gpu_damage, new);
5979 }
5980 
5981 static Bool
sna_mode_resize(ScrnInfoPtr scrn,int width,int height)5982 sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
5983 {
5984 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
5985 	struct sna *sna = to_sna(scrn);
5986 	ScreenPtr screen = xf86ScrnToScreen(scrn);
5987 	PixmapPtr new_front;
5988 	int i;
5989 
5990 	DBG(("%s (%d, %d) -> (%d, %d)\n", __FUNCTION__,
5991 	     scrn->virtualX, scrn->virtualY,
5992 	     width, height));
5993 	assert((sna->flags & SNA_IS_HOSTED) == 0);
5994 
5995 	if (scrn->virtualX == width && scrn->virtualY == height)
5996 		return TRUE;
5997 
5998 	/* Paranoid defense against rogue internal calls by Xorg */
5999 	if (width == 0 || height == 0)
6000 		return FALSE;
6001 
6002 	assert(sna->front);
6003 	assert(screen->GetScreenPixmap(screen) == sna->front);
6004 
6005 	DBG(("%s: creating new framebuffer %dx%d\n",
6006 	     __FUNCTION__, width, height));
6007 
6008 	new_front = screen->CreatePixmap(screen,
6009 					 width, height, scrn->depth,
6010 					 SNA_CREATE_FB);
6011 	if (!new_front)
6012 		return FALSE;
6013 
6014 	xf86DrvMsg(scrn->scrnIndex, X_INFO,
6015 		   "resizing framebuffer to %dx%d\n",
6016 		   width, height);
6017 
6018 	for (i = 0; i < sna->mode.num_real_crtc; i++)
6019 		sna_crtc_disable_shadow(sna, to_sna_crtc(config->crtc[i]));
6020 	assert(sna->mode.shadow_active == 0);
6021 	assert(!sna->mode.shadow_enabled);
6022 	assert(sna->mode.shadow_damage == NULL);
6023 	assert(sna->mode.shadow == NULL);
6024 
6025 	/* Flush pending shadow updates */
6026 	if (sna->mode.flip_active) {
6027 		DBG(("%s: waiting for %d outstanding TearFree flips\n",
6028 		     __FUNCTION__, sna->mode.flip_active));
6029 		while (sna->mode.flip_active && sna_mode_wait_for_event(sna))
6030 			sna_mode_wakeup(sna);
6031 	}
6032 
6033 	/* Cancel a pending [un]flip (as the pixmaps no longer match) */
6034 	sna_present_cancel_flip(sna);
6035 	copy_front(sna, sna->front, new_front);
6036 
6037 	screen->SetScreenPixmap(new_front);
6038 	assert(screen->GetScreenPixmap(screen) == new_front);
6039 	assert(sna->front == new_front);
6040 	screen->DestroyPixmap(new_front); /* owned by screen now */
6041 
6042 	scrn->virtualX = width;
6043 	scrn->virtualY = height;
6044 	scrn->displayWidth = width;
6045 
6046 	/* Only update the CRTCs if we are in control */
6047 	if (!scrn->vtSema)
6048 		return TRUE;
6049 
6050 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
6051 		xf86CrtcPtr crtc = config->crtc[i];
6052 
6053 		assert(to_sna_crtc(crtc) != NULL);
6054 		if (to_sna_crtc(crtc)->bo == NULL)
6055 			continue;
6056 
6057 		if (!__sna_crtc_set_mode(crtc))
6058 			sna_crtc_disable(crtc, false);
6059 	}
6060 
6061 	sna_mode_wakeup(sna);
6062 	kgem_clean_scanout_cache(&sna->kgem);
6063 
6064 	return TRUE;
6065 }
6066 
6067 /* cursor handling */
6068 static void
rotate_coord(Rotation rotation,int size,int x_dst,int y_dst,int * x_src,int * y_src)6069 rotate_coord(Rotation rotation, int size,
6070 	     int x_dst, int y_dst,
6071 	     int *x_src, int *y_src)
6072 {
6073 	int t;
6074 
6075 	switch (rotation & 0xf) {
6076 	case RR_Rotate_0:
6077 		break;
6078 	case RR_Rotate_90:
6079 		t = x_dst;
6080 		x_dst = size - y_dst - 1;
6081 		y_dst = t;
6082 		break;
6083 	case RR_Rotate_180:
6084 		x_dst = size - x_dst - 1;
6085 		y_dst = size - y_dst - 1;
6086 		break;
6087 	case RR_Rotate_270:
6088 		t = x_dst;
6089 		x_dst = y_dst;
6090 		y_dst = size - t - 1;
6091 		break;
6092 	}
6093 
6094 	if (rotation & RR_Reflect_X)
6095 		x_dst = size - x_dst - 1;
6096 	if (rotation & RR_Reflect_Y)
6097 		y_dst = size - y_dst - 1;
6098 
6099 	*x_src = x_dst;
6100 	*y_src = y_dst;
6101 }
6102 
__sna_create_cursor(struct sna * sna,int size)6103 static struct sna_cursor *__sna_create_cursor(struct sna *sna, int size)
6104 {
6105 	struct sna_cursor *c;
6106 
6107 	for (c = sna->cursor.cursors; c; c = c->next) {
6108 		if (c->ref == 0 && c->alloc >= size) {
6109 			__DBG(("%s: stealing handle=%d, serial=%d, rotation=%d, alloc=%d\n",
6110 			       __FUNCTION__, c->handle, c->serial, c->rotation, c->alloc));
6111 			return c;
6112 		}
6113 	}
6114 
6115 	__DBG(("%s(size=%d, num_stash=%d)\n", __FUNCTION__, size, sna->cursor.num_stash));
6116 
6117 	c = sna->cursor.stash;
6118 	assert(c);
6119 
6120 	c->alloc = ALIGN(size, 4096);
6121 	c->handle = gem_create(sna->kgem.fd, c->alloc);
6122 	if (c->handle == 0)
6123 		return NULL;
6124 
6125 	/* Old hardware uses physical addresses, which the kernel
6126 	 * implements in an incoherent fashion requiring a pwrite.
6127 	 */
6128 	if (sna->cursor.use_gtt) {
6129 		c->image = gem_mmap(sna->kgem.fd, c->handle, c->alloc);
6130 		if (c->image == NULL) {
6131 			gem_close(sna->kgem.fd, c->handle);
6132 			return NULL;
6133 		}
6134 	} else
6135 		c->image = NULL;
6136 
6137 	__DBG(("%s: handle=%d, allocated %d\n", __FUNCTION__, c->handle, size));
6138 
6139 	c->ref = 0;
6140 	c->serial = 0;
6141 	c->rotation = 0;
6142 	c->last_width = c->last_height = 0; /* all clear */
6143 	c->size = size;
6144 
6145 	sna->cursor.num_stash--;
6146 	sna->cursor.stash = c->next;
6147 
6148 	c->next = sna->cursor.cursors;
6149 	sna->cursor.cursors = c;
6150 
6151 	return c;
6152 }
6153 
get_cursor_argb(CursorPtr c)6154 static uint32_t *get_cursor_argb(CursorPtr c)
6155 {
6156 #ifdef ARGB_CURSOR
6157 	return (uint32_t *)c->bits->argb;
6158 #else
6159 	return NULL;
6160 #endif
6161 }
6162 
__cursor_size(int width,int height)6163 static int __cursor_size(int width, int height)
6164 {
6165 	int i, size;
6166 
6167 	i = MAX(width, height);
6168 	for (size = 64; size < i; size <<= 1)
6169 		;
6170 
6171 	return size;
6172 }
6173 
__sna_get_cursor(struct sna * sna,xf86CrtcPtr crtc)6174 static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
6175 {
6176 	struct sna_cursor *cursor;
6177 	const uint8_t *source, *mask;
6178 	const uint32_t *argb;
6179 	uint32_t *image;
6180 	int width, height, pitch, size, x, y;
6181 	bool transformed;
6182 	Rotation rotation;
6183 
6184 	assert(sna->cursor.ref);
6185 
6186 	cursor = to_sna_crtc(crtc)->cursor;
6187 	__DBG(("%s: current cursor handle=%d, serial=%d [expected %d]\n",
6188 	       __FUNCTION__,
6189 	       cursor ? cursor->handle : 0,
6190 	       cursor ? cursor->serial : 0,
6191 	       sna->cursor.serial));
6192 	if (cursor && cursor->serial == sna->cursor.serial) {
6193 		assert(cursor->size == sna->cursor.size || cursor->transformed);
6194 		assert(cursor->rotation == (!to_sna_crtc(crtc)->cursor_transform && crtc->transform_in_use) ? crtc->rotation : RR_Rotate_0);
6195 		assert(cursor->ref);
6196 		return cursor;
6197 	}
6198 
6199 	__DBG(("%s: cursor=%dx%d, pitch=%d, serial=%d, argb?=%d\n", __FUNCTION__,
6200 	       sna->cursor.ref->bits->width,
6201 	       sna->cursor.ref->bits->height,
6202 	       get_cursor_argb(sna->cursor.ref) ? 4*sna->cursor.ref->bits->width : BitmapBytePad(sna->cursor.ref->bits->width),
6203 	       sna->cursor.serial,
6204 	       get_cursor_argb(sna->cursor.ref) != NULL));
6205 
6206 	transformed = to_sna_crtc(crtc)->cursor_transform;
6207 	rotation = (!transformed && crtc->transform_in_use) ? crtc->rotation : RR_Rotate_0;
6208 
6209 	if (transformed) {
6210 		struct pixman_box16 box;
6211 
6212 		box.x1 = box.y1 = 0;
6213 		box.x2 = sna->cursor.ref->bits->width;
6214 		box.y2 = sna->cursor.ref->bits->height;
6215 
6216 		pixman_f_transform_bounds(&crtc->f_crtc_to_framebuffer, &box);
6217 		size = __cursor_size(box.x2 - box.x1, box.y2 - box.y1);
6218 		__DBG(("%s: transformed cursor %dx%d -> %dx%d\n",
6219 		       __FUNCTION__ ,
6220 		       sna->cursor.ref->bits->width,
6221 		       sna->cursor.ref->bits->height,
6222 		       box.x2 - box.x1, box.y2 - box.y1));
6223 	} else
6224 		size = sna->cursor.size;
6225 
6226 	if (crtc->transform_in_use) {
6227 		RRTransformPtr T = NULL;
6228 		struct pixman_vector v;
6229 
6230 		if (crtc->transformPresent) {
6231 			T = &crtc->transform;
6232 
6233 			/* Cancel any translation from this affine
6234 			 * transformation. We just want to rotate and scale
6235 			 * the cursor image.
6236 			 */
6237 			v.vector[0] = 0;
6238 			v.vector[1] = 0;
6239 			v.vector[2] = pixman_fixed_1;
6240 			pixman_transform_point(&crtc->transform.transform, &v);
6241 		}
6242 
6243 		RRTransformCompute(0, 0, size, size, crtc->rotation, T, NULL,
6244 				   &to_sna_crtc(crtc)->cursor_to_fb,
6245 				   &to_sna_crtc(crtc)->fb_to_cursor);
6246 		if (T)
6247 			pixman_f_transform_translate(
6248 					&to_sna_crtc(crtc)->cursor_to_fb,
6249 					&to_sna_crtc(crtc)->fb_to_cursor,
6250 					-pixman_fixed_to_double(v.vector[0]),
6251 					-pixman_fixed_to_double(v.vector[1]));
6252 
6253 		__DBG(("%s: cursor_to_fb [%f %f %f, %f %f %f, %f %f %f]\n",
6254 		       __FUNCTION__,
6255 		       to_sna_crtc(crtc)->cursor_to_fb.m[0][0],
6256 		       to_sna_crtc(crtc)->cursor_to_fb.m[0][1],
6257 		       to_sna_crtc(crtc)->cursor_to_fb.m[0][2],
6258 		       to_sna_crtc(crtc)->cursor_to_fb.m[1][0],
6259 		       to_sna_crtc(crtc)->cursor_to_fb.m[1][1],
6260 		       to_sna_crtc(crtc)->cursor_to_fb.m[1][2],
6261 		       to_sna_crtc(crtc)->cursor_to_fb.m[2][0],
6262 		       to_sna_crtc(crtc)->cursor_to_fb.m[2][1],
6263 		       to_sna_crtc(crtc)->cursor_to_fb.m[2][2]));
6264 	}
6265 
6266 	/* Don't allow phys cursor sharing */
6267 	if (sna->cursor.use_gtt && !transformed) {
6268 		for (cursor = sna->cursor.cursors; cursor; cursor = cursor->next) {
6269 			if (cursor->serial == sna->cursor.serial &&
6270 			    cursor->rotation == rotation &&
6271 			    !cursor->transformed) {
6272 				__DBG(("%s: reusing handle=%d, serial=%d, rotation=%d, size=%d\n",
6273 				       __FUNCTION__, cursor->handle, cursor->serial, cursor->rotation, cursor->size));
6274 				assert(cursor->size == sna->cursor.size);
6275 				return cursor;
6276 			}
6277 		}
6278 	}
6279 
6280 	cursor = to_sna_crtc(crtc)->cursor;
6281 	if (cursor && cursor->alloc < 4*size*size)
6282 		cursor = NULL;
6283 
6284 	if (cursor == NULL) {
6285 		cursor = __sna_create_cursor(sna, 4*size*size);
6286 		if (cursor == NULL) {
6287 			DBG(("%s: failed to allocate cursor\n", __FUNCTION__));
6288 			return NULL;
6289 		}
6290 	}
6291 
6292 	width  = sna->cursor.ref->bits->width;
6293 	height = sna->cursor.ref->bits->height;
6294 	source = sna->cursor.ref->bits->source;
6295 	mask = sna->cursor.ref->bits->mask;
6296 	argb = get_cursor_argb(sna->cursor.ref);
6297 	pitch = BitmapBytePad(width);
6298 
6299 	image = cursor->image;
6300 	if (image == NULL || transformed) {
6301 		image = sna->cursor.scratch;
6302 		cursor->last_width = cursor->last_height = size;
6303 	}
6304 	if (size > cursor->size ||
6305 	    width < cursor->last_width ||
6306 	    height < cursor->last_height ||
6307 	    rotation != cursor->rotation)
6308 		memset(image, 0, 4*size*size);
6309 	if (rotation == RR_Rotate_0) {
6310 		if (argb == NULL) {
6311 			for (y = 0; y < height; y++) {
6312 				uint32_t *p = image + y*size;
6313 				for (x = 0; x < width; x++) {
6314 					int byte = x / 8;
6315 					uint8_t bit = 1 << (x & 7);
6316 					uint32_t pixel;
6317 
6318 					if (mask[byte] & bit) {
6319 						if (source[byte] & bit)
6320 							pixel = sna->cursor.fg;
6321 						else
6322 							pixel = sna->cursor.bg;
6323 					} else
6324 						pixel = 0;
6325 
6326 					*p++ = pixel;
6327 				}
6328 				mask += pitch;
6329 				source += pitch;
6330 			}
6331 			if (transformed) {
6332 				__DBG(("%s: Applying affine BLT to bitmap\n", __FUNCTION__));
6333 				affine_blt(image, cursor->image, 32,
6334 					   0, 0, width, height, size * 4,
6335 					   0, 0, size, size, size * 4,
6336 					   &to_sna_crtc(crtc)->cursor_to_fb);
6337 				image = cursor->image;
6338 			}
6339 		} else if (transformed) {
6340 			__DBG(("%s: Applying affine BLT to ARGB\n", __FUNCTION__));
6341 			affine_blt(argb, cursor->image, 32,
6342 				   0, 0, width, height, width * 4,
6343 				   0, 0, size, size, size * 4,
6344 				   &to_sna_crtc(crtc)->cursor_to_fb);
6345 			image = cursor->image;
6346 		} else
6347 			memcpy_blt(argb, image, 32,
6348 				   width * 4, size * 4,
6349 				   0, 0,
6350 				   0, 0,
6351 				   width, height);
6352 	} else {
6353 		for (y = 0; y < size; y++)
6354 			for (x = 0; x < size; x++) {
6355 				uint32_t pixel;
6356 				int xin, yin;
6357 
6358 				rotate_coord(rotation, size, x, y, &xin, &yin);
6359 				if (xin < width && yin < height)
6360 					if (argb == NULL) {
6361 						int byte = xin / 8;
6362 						int bit = xin & 7;
6363 						if (mask[yin*pitch + byte] & (1 << bit)) {
6364 							if (source[yin*pitch + byte] & (1 << bit))
6365 								pixel = sna->cursor.fg;
6366 							else
6367 								pixel = sna->cursor.bg;
6368 						} else
6369 							pixel = 0;
6370 					} else
6371 						pixel = argb[yin * width + xin];
6372 				else
6373 					pixel = 0;
6374 				image[y * size + x] = pixel;
6375 			}
6376 	}
6377 
6378 	if (image != cursor->image) {
6379 		struct drm_i915_gem_pwrite pwrite;
6380 
6381 		VG_CLEAR(pwrite);
6382 		pwrite.handle = cursor->handle;
6383 		pwrite.offset = 0;
6384 		pwrite.size = 4*size*size;
6385 		pwrite.data_ptr = (uintptr_t)image;
6386 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite))
6387 			__DBG(("%s: cursor update (pwrite) failed: %d\n", __FUNCTION__, errno));
6388 	}
6389 
6390 	cursor->size = size;
6391 	cursor->rotation = rotation;
6392 	cursor->transformed = transformed;
6393 	cursor->serial = sna->cursor.serial;
6394 	if (transformed) {
6395 		/* mark the transformed rectangle as dirty, not input */
6396 		cursor->last_width = size;
6397 		cursor->last_height = size;
6398 	} else {
6399 		cursor->last_width = width;
6400 		cursor->last_height = height;
6401 	}
6402 	return cursor;
6403 }
6404 
6405 static unsigned char *
sna_realize_cursor(xf86CursorInfoPtr info,CursorPtr cursor)6406 sna_realize_cursor(xf86CursorInfoPtr info, CursorPtr cursor)
6407 {
6408 	return NULL;
6409 }
6410 
__restore_swcursor(ScrnInfoPtr scrn)6411 static void __restore_swcursor(ScrnInfoPtr scrn)
6412 {
6413 	struct sna *sna = to_sna(scrn);
6414 
6415 	DBG(("%s: attempting to restore SW cursor\n", __FUNCTION__));
6416 	xf86CursorResetCursor(scrn->pScreen);
6417 
6418 	/* Try to switch back to the HW cursor on the next cursor update */
6419 	sna->cursor.disable = false;
6420 
6421 	RemoveBlockAndWakeupHandlers((void *)__restore_swcursor,
6422 				     (void *)NoopDDA,
6423 				     scrn);
6424 }
6425 
restore_swcursor(struct sna * sna)6426 static void restore_swcursor(struct sna *sna)
6427 {
6428 	sna->cursor.info->HideCursor(sna->scrn);
6429 
6430 	/* XXX Force the cursor to be restored (avoiding recursion) */
6431 	FreeCursor(sna->cursor.ref, None);
6432 	sna->cursor.ref = NULL;
6433 
6434 	RegisterBlockAndWakeupHandlers((void *)__restore_swcursor,
6435 				       (void *)NoopDDA,
6436 				       sna->scrn);
6437 }
6438 
6439 static void
sna_show_cursors(ScrnInfoPtr scrn)6440 sna_show_cursors(ScrnInfoPtr scrn)
6441 {
6442 	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
6443 	struct sna *sna = to_sna(scrn);
6444 	struct kmsg kmsg;
6445 	int sigio, c;
6446 
6447 	DBG(("%s: cursor?=%d\n", __FUNCTION__, sna->cursor.ref != NULL));
6448 	if (sna->cursor.ref == NULL)
6449 		return;
6450 
6451 	kmsg_open(&kmsg);
6452 	sigio = sigio_block();
6453 	for (c = 0; c < sna->mode.num_real_crtc; c++) {
6454 		xf86CrtcPtr crtc = xf86_config->crtc[c];
6455 		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
6456 		struct drm_mode_cursor arg;
6457 		struct sna_cursor *cursor;
6458 
6459 		assert(sna_crtc != NULL);
6460 		if (sna_crtc->bo == NULL)
6461 			continue;
6462 
6463 		if (!crtc->cursor_in_range) {
6464 			DBG(("%s: skipping cursor outside CRTC (pipe=%d)\n",
6465 			     __FUNCTION__, sna_crtc_pipe(crtc)));
6466 			continue;
6467 		}
6468 
6469 		cursor = __sna_get_cursor(sna, crtc);
6470 		if (cursor == NULL ||
6471 		    (sna_crtc->cursor == cursor && sna_crtc->last_cursor_size == cursor->size)) {
6472 			DBG(("%s: skipping cursor already show on CRTC (pipe=%d)\n",
6473 			     __FUNCTION__, sna_crtc_pipe(crtc)));
6474 			continue;
6475 		}
6476 
6477 		DBG(("%s: CRTC pipe=%d, handle->%d\n", __FUNCTION__,
6478 		     sna_crtc_pipe(crtc), cursor->handle));
6479 
6480 		VG_CLEAR(arg);
6481 		arg.flags = DRM_MODE_CURSOR_BO;
6482 		arg.crtc_id = __sna_crtc_id(sna_crtc);
6483 		arg.width = arg.height = cursor->size;
6484 		arg.handle = cursor->handle;
6485 
6486 		if (!FAIL_CURSOR_IOCTL &&
6487 		    drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg) == 0) {
6488 			if (sna_crtc->cursor) {
6489 				assert(sna_crtc->cursor->ref > 0);
6490 				sna_crtc->cursor->ref--;
6491 			}
6492 			cursor->ref++;
6493 			sna_crtc->cursor = cursor;
6494 			sna_crtc->last_cursor_size = cursor->size;
6495 		} else {
6496 			ERR(("%s: failed to show cursor on CRTC:%d [pipe=%d], disabling hwcursor: errno=%d\n",
6497 			     __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc), errno));
6498 			sna->cursor.disable = true;
6499 		}
6500 	}
6501 	sigio_unblock(sigio);
6502 	sna->cursor.active = true;
6503 	kmsg_close(&kmsg, sna->cursor.disable);
6504 
6505 	if (unlikely(sna->cursor.disable))
6506 		restore_swcursor(sna);
6507 }
6508 
6509 static void
sna_set_cursor_colors(ScrnInfoPtr scrn,int _bg,int _fg)6510 sna_set_cursor_colors(ScrnInfoPtr scrn, int _bg, int _fg)
6511 {
6512 	struct sna *sna = to_sna(scrn);
6513 	uint32_t fg = _fg, bg = _bg;
6514 
6515 	__DBG(("%s(bg=%08x, fg=%08x)\n", __FUNCTION__, bg, fg));
6516 
6517 	/* Save ARGB versions of these colors */
6518 	fg |= 0xff000000;
6519 	bg |= 0xff000000;
6520 	if (fg == sna->cursor.fg && bg == sna->cursor.bg)
6521 		return;
6522 
6523 	sna->cursor.fg = fg;
6524 	sna->cursor.bg = bg;
6525 
6526 	if (sna->cursor.ref == NULL)
6527 		return;
6528 
6529 	if (get_cursor_argb(sna->cursor.ref))
6530 		return;
6531 
6532 	sna->cursor.serial++;
6533 	__DBG(("%s: serial->%d\n", __FUNCTION__, sna->cursor.serial));
6534 
6535 	sna_show_cursors(scrn);
6536 }
6537 
6538 static void
sna_crtc_disable_cursor(struct sna * sna,struct sna_crtc * crtc)6539 sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc)
6540 {
6541 	struct drm_mode_cursor arg;
6542 	int sigio;
6543 
6544 	if (!crtc->cursor)
6545 		return;
6546 
6547 	sigio = sigio_block();
6548 	if (crtc->cursor) {
6549 		DBG(("%s: CRTC:%d, handle=%d\n", __FUNCTION__, __sna_crtc_id(crtc), crtc->cursor->handle));
6550 		assert(crtc->cursor->ref > 0);
6551 		crtc->cursor->ref--;
6552 		crtc->cursor = NULL;
6553 		crtc->last_cursor_size = 0;
6554 
6555 		VG_CLEAR(arg);
6556 		arg.flags = DRM_MODE_CURSOR_BO;
6557 		arg.crtc_id = __sna_crtc_id(crtc);
6558 		arg.width = arg.height = 0;
6559 		arg.handle = 0;
6560 
6561 		(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg);
6562 	}
6563 	sigio_unblock(sigio);
6564 }
6565 
6566 static void
sna_disable_cursors(ScrnInfoPtr scrn)6567 sna_disable_cursors(ScrnInfoPtr scrn)
6568 {
6569 	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
6570 	struct sna *sna = to_sna(scrn);
6571 	int sigio, c;
6572 
6573 	DBG(("%s\n", __FUNCTION__));
6574 
6575 	sigio = sigio_block();
6576 	for (c = 0; c < sna->mode.num_real_crtc; c++) {
6577 		assert(to_sna_crtc(xf86_config->crtc[c]));
6578 		sna_crtc_disable_cursor(sna, to_sna_crtc(xf86_config->crtc[c]));
6579 	}
6580 	sigio_unblock(sigio);
6581 }
6582 
6583 static void
sna_hide_cursors(ScrnInfoPtr scrn)6584 sna_hide_cursors(ScrnInfoPtr scrn)
6585 {
6586 	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
6587 	struct sna *sna = to_sna(scrn);
6588 	struct sna_cursor *cursor, **prev;
6589 	int sigio, c;
6590 
6591 	DBG(("%s\n", __FUNCTION__));
6592 	sna->cursor.active = false;
6593 
6594 	sigio = sigio_block();
6595 	for (c = 0; c < sna->mode.num_real_crtc; c++) {
6596 		assert(to_sna_crtc(xf86_config->crtc[c]));
6597 		sna_crtc_disable_cursor(sna, to_sna_crtc(xf86_config->crtc[c]));
6598 	}
6599 
6600 	for (prev = &sna->cursor.cursors; (cursor = *prev) != NULL; ) {
6601 		assert(cursor->ref == 0);
6602 
6603 		if (cursor->serial == sna->cursor.serial) {
6604 			prev = &cursor->next;
6605 			continue;
6606 		}
6607 
6608 		*prev = cursor->next;
6609 		if (cursor->image)
6610 			munmap(cursor->image, cursor->alloc);
6611 		gem_close(sna->kgem.fd, cursor->handle);
6612 
6613 		cursor->next = sna->cursor.stash;
6614 		sna->cursor.stash = cursor;
6615 		sna->cursor.num_stash++;
6616 	}
6617 
6618 	sigio_unblock(sigio);
6619 }
6620 
6621 static void
sna_set_cursor_position(ScrnInfoPtr scrn,int x,int y)6622 sna_set_cursor_position(ScrnInfoPtr scrn, int x, int y)
6623 {
6624 	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
6625 	struct sna *sna = to_sna(scrn);
6626 	struct kmsg kmsg;
6627 	int sigio, c;
6628 
6629 	__DBG(("%s(%d, %d), cursor? %d\n", __FUNCTION__,
6630 	       x, y, sna->cursor.ref!=NULL));
6631 	if (sna->cursor.ref == NULL)
6632 		return;
6633 
6634 	kmsg_open(&kmsg);
6635 	sigio = sigio_block();
6636 	sna->cursor.last_x = x;
6637 	sna->cursor.last_y = y;
6638 
6639 	/* undo what xf86HWCurs did to the coordinates */
6640 	x += scrn->frameX0;
6641 	y += scrn->frameY0;
6642 	for (c = 0; c < sna->mode.num_real_crtc; c++) {
6643 		xf86CrtcPtr crtc = xf86_config->crtc[c];
6644 		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
6645 		struct sna_cursor *cursor = NULL;
6646 		struct drm_mode_cursor arg;
6647 
6648 		assert(sna_crtc != NULL);
6649 
6650 		VG_CLEAR(arg);
6651 		arg.flags = 0;
6652 		arg.crtc_id = __sna_crtc_id(sna_crtc);
6653 		arg.handle = 0;
6654 
6655 		if (sna_crtc->bo == NULL)
6656 			goto disable;
6657 
6658 		cursor = __sna_get_cursor(sna, crtc);
6659 		if (cursor == NULL)
6660 			cursor = sna_crtc->cursor;
6661 		if (cursor == NULL) {
6662 			__DBG(("%s: failed to grab cursor, disabling\n", __FUNCTION__));
6663 			goto disable;
6664 		}
6665 
6666 		if (crtc->transform_in_use) {
6667 			int xhot = sna->cursor.ref->bits->xhot;
6668 			int yhot = sna->cursor.ref->bits->yhot;
6669 			struct pict_f_vector v, hot;
6670 
6671 			v.v[0] = x + xhot + .5;
6672 			v.v[1] = y + yhot + .5;
6673 			v.v[2] = 1.;
6674 			pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &v);
6675 
6676 			hot.v[0] = xhot;
6677 			hot.v[1] = yhot;
6678 			hot.v[2] = 1.;
6679 			pixman_f_transform_point(&sna_crtc->fb_to_cursor, &hot);
6680 
6681 			arg.x = floor(v.v[0] - hot.v[0]);
6682 			arg.y = floor(v.v[1] - hot.v[1]);
6683 		} else {
6684 			arg.x = x - crtc->x;
6685 			arg.y = y - crtc->y;
6686 		}
6687 
6688 		if (arg.x < crtc->mode.HDisplay && arg.x > -sna->cursor.size &&
6689 		    arg.y < crtc->mode.VDisplay && arg.y > -sna->cursor.size) {
6690 			if (sna_crtc->cursor != cursor || sna_crtc->last_cursor_size != cursor->size) {
6691 				arg.flags |= DRM_MODE_CURSOR_BO;
6692 				arg.handle = cursor->handle;
6693 			}
6694 
6695 			arg.width = arg.height = cursor->size;
6696 			arg.flags |= DRM_MODE_CURSOR_MOVE;
6697 			crtc->cursor_in_range = true;
6698 		} else {
6699 			crtc->cursor_in_range = false;
6700 disable:
6701 			if (sna_crtc->cursor) {
6702 				arg.flags = DRM_MODE_CURSOR_BO;
6703 				arg.width = arg.height = 0;
6704 			}
6705 			cursor = NULL;
6706 		}
6707 
6708 		__DBG(("%s: CRTC:%d (%d, %d), handle=%d, flags=%x (old cursor handle=%d), move? %d, update handle? %d\n",
6709 		       __FUNCTION__, __sna_crtc_id(sna_crtc), arg.x, arg.y, arg.handle, arg.flags, sna_crtc->cursor ? sna_crtc->cursor->handle : 0,
6710 		       arg.flags & DRM_MODE_CURSOR_MOVE, arg.flags & DRM_MODE_CURSOR_BO));
6711 
6712 		if (arg.flags == 0)
6713 			continue;
6714 
6715 		if (!FAIL_CURSOR_IOCTL &&
6716 		    drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg) == 0) {
6717 			if (arg.flags & DRM_MODE_CURSOR_BO) {
6718 				if (sna_crtc->cursor) {
6719 					assert(sna_crtc->cursor->ref > 0);
6720 					sna_crtc->cursor->ref--;
6721 				}
6722 				sna_crtc->cursor = cursor;
6723 				if (cursor) {
6724 					sna_crtc->last_cursor_size = cursor->size;
6725 					cursor->ref++;
6726 				} else
6727 					sna_crtc->last_cursor_size = 0;
6728 			}
6729 		} else {
6730 			ERR(("%s: failed to update cursor on CRTC:%d [pipe=%d], disabling hwcursor: errno=%d\n",
6731 			     __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc), errno));
6732 			/* XXX How to force switch back to SW cursor?
6733 			 * Right now we just want until the next cursor image
6734 			 * change, which is fairly frequent.
6735 			 */
6736 			sna->cursor.disable = true;
6737 		}
6738 	}
6739 	sigio_unblock(sigio);
6740 	kmsg_close(&kmsg, sna->cursor.disable);
6741 
6742 	if (unlikely(sna->cursor.disable))
6743 		restore_swcursor(sna);
6744 }
6745 
6746 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,2)
6747 static Bool
sna_load_cursor_argb2(ScrnInfoPtr scrn,CursorPtr cursor)6748 sna_load_cursor_argb2(ScrnInfoPtr scrn, CursorPtr cursor)
6749 {
6750 	return TRUE;
6751 }
6752 
6753 static Bool
sna_load_cursor_image2(ScrnInfoPtr scrn,unsigned char * src)6754 sna_load_cursor_image2(ScrnInfoPtr scrn, unsigned char *src)
6755 {
6756 	return TRUE;
6757 }
6758 #endif
6759 
6760 static void
sna_load_cursor_argb(ScrnInfoPtr scrn,CursorPtr cursor)6761 sna_load_cursor_argb(ScrnInfoPtr scrn, CursorPtr cursor)
6762 {
6763 }
6764 
6765 static void
sna_load_cursor_image(ScrnInfoPtr scrn,unsigned char * src)6766 sna_load_cursor_image(ScrnInfoPtr scrn, unsigned char *src)
6767 {
6768 }
6769 
6770 static bool
sna_cursor_preallocate(struct sna * sna)6771 sna_cursor_preallocate(struct sna *sna)
6772 {
6773 	while (sna->cursor.num_stash < 0) {
6774 		struct sna_cursor *cursor = malloc(sizeof(*cursor));
6775 		if (!cursor)
6776 			return false;
6777 
6778 		cursor->next = sna->cursor.stash;
6779 		sna->cursor.stash = cursor;
6780 
6781 		sna->cursor.num_stash++;
6782 	}
6783 
6784 	return true;
6785 }
6786 
6787 static bool
transformable_cursor(struct sna * sna,CursorPtr cursor)6788 transformable_cursor(struct sna *sna, CursorPtr cursor)
6789 {
6790 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
6791 	int i;
6792 
6793 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
6794 		xf86CrtcPtr crtc = config->crtc[i];
6795 		struct pixman_box16 box;
6796 		int size;
6797 
6798 		if (!to_sna_crtc(crtc)->hwcursor) {
6799 			DBG(("%s: hwcursor disabled on CRTC:%d [pipe=%d]\n",
6800 			     __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc)));
6801 			return false;
6802 		}
6803 
6804 		if (!sna->cursor.use_gtt || !sna->cursor.scratch) {
6805 			DBG(("%s: unable to use GTT curosor access [%d] or no scratch [%d]\n",
6806 			     __FUNCTION__, sna->cursor.use_gtt, sna->cursor.scratch));
6807 			return false;
6808 		}
6809 
6810 		box.x1 = box.y1 = 0;
6811 		box.x2 = cursor->bits->width;
6812 		box.y2 = cursor->bits->height;
6813 
6814 		if (!pixman_f_transform_bounds(&crtc->f_crtc_to_framebuffer,
6815 					       &box)) {
6816 			DBG(("%s: unable to transform bounds\n", __FUNCTION__));
6817 			return false;
6818 		}
6819 
6820 		size = __cursor_size(box.x2 - box.x1, box.y2 - box.y1);
6821 		if (size > sna->cursor.max_size) {
6822 			DBG(("%s: transformed cursor size=%d too large, max=%d\n",
6823 			     __FUNCTION__, size, sna->cursor.max_size));
6824 			return false;
6825 		}
6826 	}
6827 
6828 	return true;
6829 }
6830 
6831 static Bool
sna_use_hw_cursor(ScreenPtr screen,CursorPtr cursor)6832 sna_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
6833 {
6834 	struct sna *sna = to_sna_from_screen(screen);
6835 
6836 	DBG(("%s (%dx%d)?\n", __FUNCTION__,
6837 	     cursor->bits->width, cursor->bits->height));
6838 
6839 	if (sna->cursor.disable)
6840 		return FALSE;
6841 
6842 	/* cursors are invariant */
6843 	if (cursor == sna->cursor.ref)
6844 		return TRUE;
6845 
6846 	if (sna->cursor.ref) {
6847 		FreeCursor(sna->cursor.ref, None);
6848 		sna->cursor.ref = NULL;
6849 	}
6850 
6851 	sna->cursor.size =
6852 		__cursor_size(cursor->bits->width, cursor->bits->height);
6853 	if (sna->cursor.size > sna->cursor.max_size) {
6854 		DBG(("%s: cursor size=%d too large, max %d: using sw cursor\n",
6855 		     __FUNCTION__, sna->cursor.size, sna->cursor.max_size));
6856 		return FALSE;
6857 	}
6858 
6859 	if (sna->mode.rr_active && !transformable_cursor(sna, cursor)) {
6860 		DBG(("%s: RandR active [%d] and non-transformable cursor: using sw cursor\n",
6861 		     __FUNCTION__, sna->mode.rr_active));
6862 		return FALSE;
6863 	}
6864 
6865 	if (!sna_cursor_preallocate(sna)) {
6866 		DBG(("%s: cursor preallocation failed: using sw cursor\n", __FUNCTION__));
6867 		return FALSE;
6868 	}
6869 
6870 	sna->cursor.ref = cursor;
6871 	cursor->refcnt++;
6872 	sna->cursor.serial++;
6873 
6874 	DBG(("%s(%dx%d): ARGB?=%d, serial->%d, size->%d\n", __FUNCTION__,
6875 	       cursor->bits->width,
6876 	       cursor->bits->height,
6877 	       get_cursor_argb(cursor) != NULL,
6878 	       sna->cursor.serial,
6879 	       sna->cursor.size));
6880 	return TRUE;
6881 }
6882 
6883 static void
sna_cursor_pre_init(struct sna * sna)6884 sna_cursor_pre_init(struct sna *sna)
6885 {
6886 	struct local_get_cap {
6887 		uint64_t name;
6888 		uint64_t value;
6889 	} cap;
6890 	int v;
6891 
6892 	if (sna->mode.num_real_crtc == 0)
6893 		return;
6894 
6895 #define LOCAL_IOCTL_GET_CAP	DRM_IOWR(0x0c, struct local_get_cap)
6896 #ifndef DRM_CAP_CURSOR_WIDTH
6897 #define DRM_CAP_CURSOR_WIDTH	0x8
6898 #endif
6899 #ifndef DRM_CAP_CURSOR_HEIGHT
6900 #define DRM_CAP_CURSOR_HEIGHT	0x9
6901 #endif
6902 
6903 #define I915_PARAM_HAS_COHERENT_PHYS_GTT 29
6904 
6905 	sna->cursor.max_size = 64;
6906 
6907 	cap.value = 0;
6908 	cap.name = DRM_CAP_CURSOR_WIDTH;
6909 	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0)
6910 		sna->cursor.max_size = cap.value;
6911 
6912 	cap.name = DRM_CAP_CURSOR_HEIGHT;
6913 	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0 &&
6914 	    cap.value < sna->cursor.max_size)
6915 		sna->cursor.max_size = cap.value;
6916 
6917 	v = -1; /* No param uses the sign bit, reserve it for errors */
6918 	if (sna->kgem.gen >= 033) {
6919 		v = 1;
6920 	} else {
6921 		drm_i915_getparam_t gp = {
6922 			I915_PARAM_HAS_COHERENT_PHYS_GTT,
6923 			&v,
6924 		};
6925 		(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GETPARAM, &gp);
6926 	}
6927 	sna->cursor.use_gtt = v > 0;
6928 	DBG(("%s: cursor updates use_gtt?=%d\n",
6929 	     __FUNCTION__, sna->cursor.use_gtt));
6930 
6931 	sna->cursor.scratch = malloc(sna->cursor.max_size * sna->cursor.max_size * 4);
6932 	if (!sna->cursor.scratch && !sna->cursor.use_gtt)
6933 		sna->cursor.max_size = 0;
6934 
6935 	sna->cursor.num_stash = -sna->mode.num_real_crtc;
6936 
6937 	xf86DrvMsg(sna->scrn->scrnIndex, X_PROBED,
6938 		   "Using a maximum size of %dx%d for hardware cursors\n",
6939 		   sna->cursor.max_size, sna->cursor.max_size);
6940 }
6941 
6942 static void
sna_cursor_close(struct sna * sna)6943 sna_cursor_close(struct sna *sna)
6944 {
6945 	sna->cursor.serial = 0;
6946 	sna_hide_cursors(sna->scrn);
6947 
6948 	while (sna->cursor.stash) {
6949 		struct sna_cursor *cursor = sna->cursor.stash;
6950 		sna->cursor.stash = cursor->next;
6951 		free(cursor);
6952 	}
6953 
6954 	sna->cursor.num_stash = -sna->mode.num_real_crtc;
6955 }
6956 
6957 bool
sna_cursors_init(ScreenPtr screen,struct sna * sna)6958 sna_cursors_init(ScreenPtr screen, struct sna *sna)
6959 {
6960 	xf86CursorInfoPtr cursor_info;
6961 
6962 	if (sna->cursor.max_size == 0)
6963 		return false;
6964 
6965 	cursor_info = xf86CreateCursorInfoRec();
6966 	if (cursor_info == NULL)
6967 		return false;
6968 
6969 	cursor_info->MaxWidth = sna->cursor.max_size;
6970 	cursor_info->MaxHeight = sna->cursor.max_size;
6971 	cursor_info->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
6972 			      HARDWARE_CURSOR_UPDATE_UNHIDDEN |
6973 			      HARDWARE_CURSOR_ARGB);
6974 
6975 	cursor_info->RealizeCursor = sna_realize_cursor;
6976 	cursor_info->SetCursorColors = sna_set_cursor_colors;
6977 	cursor_info->SetCursorPosition = sna_set_cursor_position;
6978 	cursor_info->LoadCursorImage = sna_load_cursor_image;
6979 	cursor_info->HideCursor = sna_hide_cursors;
6980 	cursor_info->ShowCursor = sna_show_cursors;
6981 	cursor_info->UseHWCursor = sna_use_hw_cursor;
6982 #ifdef ARGB_CURSOR
6983 	cursor_info->UseHWCursorARGB = sna_use_hw_cursor;
6984 	cursor_info->LoadCursorARGB = sna_load_cursor_argb;
6985 #endif
6986 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,3)
6987 	cursor_info->LoadCursorImageCheck = sna_load_cursor_image2;
6988 #ifdef ARGB_CURSOR
6989 	cursor_info->LoadCursorARGBCheck = sna_load_cursor_argb2;
6990 #endif
6991 #endif
6992 
6993 	if (!xf86InitCursor(screen, cursor_info)) {
6994 		xf86DestroyCursorInfoRec(cursor_info);
6995 		return false;
6996 	}
6997 
6998 	sna->cursor.info = cursor_info;
6999 	return true;
7000 }
7001 
7002 static void
sna_cursors_reload(struct sna * sna)7003 sna_cursors_reload(struct sna *sna)
7004 {
7005 	DBG(("%s: active?=%d\n", __FUNCTION__, sna->cursor.active));
7006 	if (sna->cursor.active)
7007 		sna_set_cursor_position(sna->scrn,
7008 					sna->cursor.last_x,
7009 					sna->cursor.last_y);
7010 }
7011 
7012 static void
sna_cursors_fini(struct sna * sna)7013 sna_cursors_fini(struct sna *sna)
7014 {
7015 	if (sna->cursor.info) {
7016 		xf86DestroyCursorInfoRec(sna->cursor.info);
7017 		sna->cursor.info = NULL;
7018 	}
7019 
7020 	if (sna->cursor.ref) {
7021 		FreeCursor(sna->cursor.ref, None);
7022 		sna->cursor.ref = NULL;
7023 	}
7024 }
7025 
7026 static bool
sna_crtc_flip(struct sna * sna,struct sna_crtc * crtc,struct kgem_bo * bo,int x,int y)7027 sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x, int y)
7028 {
7029 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
7030 	struct drm_mode_crtc arg;
7031 	uint32_t output_ids[32];
7032 	int output_count = 0;
7033 	int i;
7034 
7035 	DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), bo->handle));
7036 
7037 	assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids));
7038 	assert(crtc->bo);
7039 	assert(crtc->kmode.clock);
7040 
7041 	for (i = 0; i < sna->mode.num_real_output; i++) {
7042 		xf86OutputPtr output = config->output[i];
7043 
7044 		if (output->crtc != crtc->base)
7045 			continue;
7046 
7047 		DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n",
7048 		     __FUNCTION__, output->name, i, to_connector_id(output),
7049 		     __sna_crtc_id(crtc), __sna_crtc_pipe(crtc),
7050 		     (uint32_t)output->possible_crtcs,
7051 		     (uint32_t)output->possible_clones));
7052 
7053 		assert(output->possible_crtcs & (1 << __sna_crtc_pipe(crtc)) ||
7054 		       is_zaphod(sna->scrn));
7055 
7056 		output_ids[output_count] = to_connector_id(output);
7057 		if (++output_count == ARRAY_SIZE(output_ids))
7058 			return false;
7059 	}
7060 	assert(output_count);
7061 
7062 	VG_CLEAR(arg);
7063 	arg.crtc_id = __sna_crtc_id(crtc);
7064 	arg.fb_id = fb_id(bo);
7065 	assert(arg.fb_id);
7066 	arg.x = x;
7067 	arg.y = y;
7068 	arg.set_connectors_ptr = (uintptr_t)output_ids;
7069 	arg.count_connectors = output_count;
7070 	arg.mode = crtc->kmode;
7071 	arg.mode_valid = 1;
7072 
7073 	DBG(("%s: applying crtc [%d, pipe=%d] mode=%dx%d+%d+%d@%d, fb=%d across %d outputs [%d...]\n",
7074 	     __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc),
7075 	     arg.mode.hdisplay,
7076 	     arg.mode.vdisplay,
7077 	     arg.x, arg.y,
7078 	     arg.mode.clock,
7079 	     arg.fb_id,
7080 	     output_count, output_count ? output_ids[0] : 0));
7081 
7082 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg))
7083 		return false;
7084 
7085 	crtc->offset = y << 16 | x;
7086 	__kgem_bo_clear_dirty(bo);
7087 	return true;
7088 }
7089 
sna_mode_restore(struct sna * sna)7090 static void sna_mode_restore(struct sna *sna)
7091 {
7092 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
7093 	int error = 0;
7094 	int i;
7095 
7096 	assert(!sna->mode.hidden);
7097 
7098 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
7099 		xf86CrtcPtr crtc = config->crtc[i];
7100 
7101 		assert(to_sna_crtc(crtc) != NULL);
7102 		if (to_sna_crtc(crtc)->bo == NULL)
7103 			continue;
7104 
7105 		assert(crtc->enabled);
7106 		if (!__sna_crtc_set_mode(crtc)) {
7107 			sna_crtc_disable(crtc, false);
7108 			error++;
7109 		}
7110 	}
7111 	sna_mode_wakeup(sna);
7112 	while (sna->mode.flip_active && sna_mode_wakeup(sna))
7113 		;
7114 	update_flush_interval(sna);
7115 	sna_cursors_reload(sna);
7116 	sna->mode.dirty = false;
7117 
7118 	if (error)
7119 		xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
7120 			   "Failed to restore display configuration\n");
7121 }
7122 
sna_needs_page_flip(struct sna * sna,struct kgem_bo * bo)7123 bool sna_needs_page_flip(struct sna *sna, struct kgem_bo *bo)
7124 {
7125 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
7126 	int i;
7127 
7128 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
7129 		struct sna_crtc *crtc = config->crtc[i]->driver_private;
7130 
7131 		if (crtc->bo == NULL)
7132 			continue;
7133 
7134 		if (crtc->bo == bo)
7135 			continue;
7136 
7137 		return true;
7138 	}
7139 
7140 	return false;
7141 }
7142 
7143 int
sna_page_flip(struct sna * sna,struct kgem_bo * bo,sna_flip_handler_t handler,void * data)7144 sna_page_flip(struct sna *sna,
7145 	      struct kgem_bo *bo,
7146 	      sna_flip_handler_t handler,
7147 	      void *data)
7148 {
7149 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
7150 	const int width = sna->scrn->virtualX;
7151 	const int height = sna->scrn->virtualY;
7152 	int sigio;
7153 	int count = 0;
7154 	int i;
7155 
7156 	DBG(("%s: handle %d attached\n", __FUNCTION__, bo->handle));
7157 	assert(bo->refcnt);
7158 
7159 	assert((sna->flags & SNA_IS_HOSTED) == 0);
7160 	assert(sna->mode.flip_active == 0);
7161 	assert(sna->mode.front_active);
7162 	assert(!sna->mode.hidden);
7163 	assert(sna->scrn->vtSema);
7164 
7165 	if ((sna->flags & (data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP)) == 0)
7166 		return 0;
7167 
7168 	kgem_bo_submit(&sna->kgem, bo);
7169 	__kgem_bo_clear_dirty(bo);
7170 
7171 	sigio = sigio_block();
7172 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
7173 		struct sna_crtc *crtc = config->crtc[i]->driver_private;
7174 		struct drm_mode_crtc_page_flip arg;
7175 		uint32_t crtc_offset;
7176 		int fixup;
7177 
7178 		DBG(("%s: crtc %d id=%d, pipe=%d active? %d\n",
7179 		     __FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->bo != NULL));
7180 		if (crtc->bo == NULL)
7181 			continue;
7182 		assert(!crtc->transform);
7183 		assert(!crtc->slave_pixmap);
7184 		assert(crtc->bo->active_scanout);
7185 		assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
7186 		assert(crtc->flip_bo == NULL);
7187 
7188 		assert_crtc_fb(sna, crtc);
7189 		if (data == NULL && crtc->bo == bo)
7190 			goto next_crtc;
7191 
7192 		arg.crtc_id = __sna_crtc_id(crtc);
7193 		arg.fb_id = get_fb(sna, bo, width, height);
7194 		if (arg.fb_id == 0) {
7195 			assert(count == 0);
7196 			break;
7197 		}
7198 
7199 		fixup = 0;
7200 		crtc_offset = crtc->base->y << 16 | crtc->base->x;
7201 
7202 		if (bo->pitch != crtc->bo->pitch || crtc_offset != crtc->offset) {
7203 			DBG(("%s: changing pitch (%d == %d) or offset (%x == %x)\n",
7204 			     __FUNCTION__,
7205 			     bo->pitch, crtc->bo->pitch,
7206 			     crtc_offset, crtc->offset));
7207 fixup_flip:
7208 			fixup = 1;
7209 			if (crtc->bo != bo && sna_crtc_flip(sna, crtc, bo, crtc->base->x, crtc->base->y)) {
7210 update_scanout:
7211 				DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n",
7212 				     __FUNCTION__, crtc->bo->handle, crtc->bo->active_scanout,
7213 				     bo->handle, bo->active_scanout));
7214 				assert(crtc->bo->active_scanout);
7215 				assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
7216 				crtc->bo->active_scanout--;
7217 				kgem_bo_destroy(&sna->kgem, crtc->bo);
7218 
7219 				if (crtc->shadow_bo) {
7220 					kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
7221 					crtc->shadow_bo = NULL;
7222 				}
7223 
7224 				crtc->bo = kgem_bo_reference(bo);
7225 				crtc->bo->active_scanout++;
7226 
7227 				if (data == NULL)
7228 					goto next_crtc;
7229 
7230 				/* queue a flip in order to send the event */
7231 			} else
7232 				goto error;
7233 		}
7234 
7235 		/* Only the reference crtc will finally deliver its page flip
7236 		 * completion event. All other crtc's events will be discarded.
7237 		 */
7238 		if (data) {
7239 			arg.user_data = (uintptr_t)crtc;
7240 			arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
7241 		} else {
7242 			arg.user_data = 0;
7243 			arg.flags = DRM_MODE_PAGE_FLIP_ASYNC;
7244 		}
7245 		arg.reserved = 0;
7246 
7247 retry_flip:
7248 		DBG(("%s: crtc %d id=%d, pipe=%d  --> fb %d\n",
7249 		     __FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), arg.fb_id));
7250 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
7251 			ERR(("%s: pageflip failed with err=%d\n", __FUNCTION__, errno));
7252 
7253 			if (errno == EBUSY) {
7254 				struct drm_mode_crtc mode;
7255 
7256 				memset(&mode, 0, sizeof(mode));
7257 				mode.crtc_id = __sna_crtc_id(crtc);
7258 				drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode);
7259 
7260 				DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=%d\n",
7261 				     __FUNCTION__,
7262 				     mode.crtc_id, mode.mode_valid,
7263 				     mode.fb_id, fb_id(crtc->bo)));
7264 
7265 				if (mode.fb_id != fb_id(crtc->bo))
7266 					goto fixup_flip;
7267 
7268 				if (count == 0)
7269 					break;
7270 
7271 				DBG(("%s: throttling on busy flip / waiting for kernel to catch up\n", __FUNCTION__));
7272 				drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_THROTTLE, 0);
7273 				sna->kgem.need_throttle = false;
7274 
7275 				goto retry_flip;
7276 			}
7277 
7278 			if (!fixup)
7279 				goto fixup_flip;
7280 
7281 error:
7282 			xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
7283 					"page flipping failed, on CRTC:%d (pipe=%d), disabling %s page flips\n",
7284 					__sna_crtc_id(crtc), __sna_crtc_pipe(crtc), data ? "synchronous": "asynchronous");
7285 
7286 			if (count || crtc->bo == bo)
7287 				sna_mode_restore(sna);
7288 
7289 			sna->flags &= ~(data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP);
7290 			count = 0;
7291 			break;
7292 		}
7293 
7294 		if (data) {
7295 			assert(crtc->flip_bo == NULL);
7296 			assert(handler);
7297 			crtc->flip_handler = handler;
7298 			crtc->flip_data = data;
7299 			crtc->flip_bo = kgem_bo_reference(bo);
7300 			crtc->flip_bo->active_scanout++;
7301 			crtc->flip_serial = crtc->mode_serial;
7302 			crtc->flip_pending = true;
7303 			sna->mode.flip_active++;
7304 
7305 			DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n",
7306 			     __FUNCTION__, __sna_crtc_id(crtc), crtc->flip_bo->handle, crtc->flip_bo->active_scanout, crtc->flip_serial));
7307 		} else
7308 			goto update_scanout;
7309 next_crtc:
7310 		count++;
7311 	}
7312 	sigio_unblock(sigio);
7313 
7314 	DBG(("%s: page flipped %d crtcs\n", __FUNCTION__, count));
7315 	return count;
7316 }
7317 
7318 static const xf86CrtcConfigFuncsRec sna_mode_funcs = {
7319 	.resize = sna_mode_resize,
7320 };
7321 
set_size_range(struct sna * sna)7322 static void set_size_range(struct sna *sna)
7323 {
7324 	/* We lie slightly as we expect no single monitor to exceed the
7325 	 * crtc limits, so if the mode exceeds the scanout restrictions,
7326 	 * we will quietly convert that to per-crtc pixmaps.
7327 	 */
7328 	xf86CrtcSetSizeRange(sna->scrn, 8, 8, INT16_MAX, INT16_MAX);
7329 }
7330 
7331 #if HAS_GAMMA
set_gamma(uint16_t * curve,int size,double value)7332 static void set_gamma(uint16_t *curve, int size, double value)
7333 {
7334 	int i;
7335 
7336 	value = 1/value;
7337 	for (i = 0; i < size; i++)
7338 		curve[i] = 256*(size-1)*pow(i/(double)(size-1), value);
7339 }
7340 
output_set_gamma(xf86OutputPtr output,xf86CrtcPtr crtc)7341 static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc)
7342 {
7343 	XF86ConfMonitorPtr mon = output->conf_monitor;
7344 
7345 	if (!mon)
7346 		return;
7347 
7348 	DBG(("%s: red=%f\n", __FUNCTION__, mon->mon_gamma_red));
7349 	if (mon->mon_gamma_red >= GAMMA_MIN &&
7350 	    mon->mon_gamma_red <= GAMMA_MAX &&
7351 	    mon->mon_gamma_red != 1.0)
7352 		set_gamma(crtc->gamma_red, crtc->gamma_size,
7353 			  mon->mon_gamma_red);
7354 
7355 	DBG(("%s: green=%f\n", __FUNCTION__, mon->mon_gamma_green));
7356 	if (mon->mon_gamma_green >= GAMMA_MIN &&
7357 	    mon->mon_gamma_green <= GAMMA_MAX &&
7358 	    mon->mon_gamma_green != 1.0)
7359 		set_gamma(crtc->gamma_green, crtc->gamma_size,
7360 			  mon->mon_gamma_green);
7361 
7362 	DBG(("%s: blue=%f\n", __FUNCTION__, mon->mon_gamma_blue));
7363 	if (mon->mon_gamma_blue >= GAMMA_MIN &&
7364 	    mon->mon_gamma_blue <= GAMMA_MAX &&
7365 	    mon->mon_gamma_blue != 1.0)
7366 		set_gamma(crtc->gamma_blue, crtc->gamma_size,
7367 			  mon->mon_gamma_blue);
7368 }
7369 
7370 static bool
crtc_get_gamma_lut(xf86CrtcPtr crtc,CARD16 * red,CARD16 * green,CARD16 * blue,int size)7371 crtc_get_gamma_lut(xf86CrtcPtr crtc,
7372 		   CARD16 *red, CARD16 *green, CARD16 *blue, int size)
7373 {
7374 
7375 	struct sna *sna = to_sna(crtc->scrn);
7376 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
7377 	struct drm_color_lut *lut = sna_crtc->gamma_lut;
7378 	struct drm_mode_get_blob blob;
7379 	int lut_size, i;
7380 
7381 	DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
7382 
7383 	memset(&blob, 0, sizeof(blob));
7384 	blob.blob_id = sna_crtc->gamma_lut_blob;
7385 
7386 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
7387 		return false;
7388 
7389 	lut_size = blob.length / sizeof(lut[0]);
7390 
7391 	if (lut_size == 0 ||
7392 	    lut_size > max(sna_crtc->gamma_lut_size, 256))
7393 		return false;
7394 
7395 	blob.data = (uintptr_t)lut;
7396 
7397 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
7398 		return false;
7399 
7400 	for (i = 0; i < size; i++) {
7401 		struct drm_color_lut *entry =
7402 			&lut[i * (lut_size - 1) / (size - 1)];
7403 
7404 		red[i] = entry->red;
7405 		green[i] = entry->green;
7406 		blue[i] = entry->blue;
7407 	}
7408 
7409 	return red[size - 1] &&
7410 		green[size - 1] &&
7411 		blue[size - 1];
7412 }
7413 
crtc_get_gamma_legacy(xf86CrtcPtr crtc,CARD16 * red,CARD16 * green,CARD16 * blue,int size)7414 static bool crtc_get_gamma_legacy(xf86CrtcPtr crtc,
7415 				  CARD16 *red,
7416 				  CARD16 *green,
7417 				  CARD16 *blue,
7418 				  int size)
7419 {
7420 	struct sna *sna = to_sna(crtc->scrn);
7421 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
7422 	struct drm_mode_crtc_lut lut = {
7423 		.crtc_id = __sna_crtc_id(sna_crtc),
7424 		.gamma_size = size,
7425 		.red = (uintptr_t)red,
7426 		.green = (uintptr_t)green,
7427 		.blue = (uintptr_t)blue,
7428 	};
7429 
7430 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) != 0)
7431 		return false;
7432 
7433 	VG(VALGRIND_MAKE_MEM_DEFINED(red, size*sizeof(red[0])));
7434 	VG(VALGRIND_MAKE_MEM_DEFINED(green, size*sizeof(green[0])));
7435 	VG(VALGRIND_MAKE_MEM_DEFINED(blue, size*sizeof(blue[0])));
7436 
7437 	return red[size - 1] &&
7438 		green[size - 1] &&
7439 		blue[size - 1];
7440 }
7441 
crtc_init_gamma(xf86CrtcPtr crtc)7442 static void crtc_init_gamma(xf86CrtcPtr crtc)
7443 {
7444 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
7445 	uint16_t *gamma;
7446 	int size;
7447 
7448 	assert(sna_crtc);
7449 
7450 	size = sna_crtc->gamma_lut_size;
7451 	if (!size)
7452 		size = 256;
7453 
7454 	/* Initialize the gamma ramps */
7455 	gamma = NULL;
7456 	if (crtc->gamma_size == size)
7457 		gamma = crtc->gamma_red;
7458 	if (gamma == NULL)
7459 		gamma = malloc(3 * size * sizeof(uint16_t));
7460 	if (gamma) {
7461 		uint16_t *red = gamma;
7462 		uint16_t *green = gamma + size;
7463 		uint16_t *blue = gamma + 2 * size;
7464 		bool gamma_set;
7465 
7466 		if (sna_crtc->gamma_lut_size)
7467 			gamma_set = crtc_get_gamma_lut(crtc, red,
7468 						       green, blue, size);
7469 		else
7470 			gamma_set = crtc_get_gamma_legacy(crtc, red,
7471 							  green, blue, size);
7472 
7473 		DBG(("%s: CRTC:%d, pipe=%d: gamma set?=%d\n",
7474 		     __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
7475 		     gamma_set));
7476 		if (!gamma_set) {
7477 			int i;
7478 
7479 			for (i = 0; i < size; i++) {
7480 				uint16_t val = i * 0xffff / (size - 1);
7481 
7482 				red[i] = val;
7483 				green[i] = val;
7484 				blue[i] = val;
7485 			}
7486 		}
7487 
7488 		if (red != crtc->gamma_red) {
7489 			free(crtc->gamma_red);
7490 			crtc->gamma_red = red;
7491 			crtc->gamma_green = green;
7492 			crtc->gamma_blue = blue;
7493 			crtc->gamma_size = size;
7494 		}
7495 	}
7496 }
7497 #else
output_set_gamma(xf86OutputPtr output,xf86CrtcPtr crtc)7498 static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc) { }
crtc_init_gamma(xf86CrtcPtr crtc)7499 static void crtc_init_gamma(xf86CrtcPtr crtc) { }
7500 #endif
7501 
preferred_mode(xf86OutputPtr output)7502 static const char *preferred_mode(xf86OutputPtr output)
7503 {
7504 	const char *mode;
7505 
7506 	mode = xf86GetOptValString(output->options, OPTION_PREFERRED_MODE);
7507 	if (mode)
7508 		return mode;
7509 
7510 	if (output->scrn->display->modes && *output->scrn->display->modes)
7511 		return *output->scrn->display->modes;
7512 
7513 	return NULL;
7514 }
7515 
sna_probe_initial_configuration(struct sna * sna)7516 static bool sna_probe_initial_configuration(struct sna *sna)
7517 {
7518 	ScrnInfoPtr scrn = sna->scrn;
7519 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
7520 	int crtc_active, crtc_enabled;
7521 	int width, height;
7522 	int i, j;
7523 
7524 	assert((sna->flags & SNA_IS_HOSTED) == 0);
7525 
7526 	if ((sna->flags & SNA_IS_SLAVED) == 0) {
7527 		const int user_overrides[] = {
7528 			OPTION_POSITION,
7529 			OPTION_BELOW,
7530 			OPTION_RIGHT_OF,
7531 			OPTION_ABOVE,
7532 			OPTION_LEFT_OF,
7533 			OPTION_ROTATE,
7534 			OPTION_PANNING,
7535 		};
7536 		if (xf86ReturnOptValBool(sna->Options, OPTION_REPROBE, FALSE)) {
7537 			DBG(("%s: user requests reprobing\n", __FUNCTION__));
7538 			return false;
7539 		}
7540 
7541 		/* First scan through all outputs and look for user overrides */
7542 		for (i = 0; i < sna->mode.num_real_output; i++) {
7543 			xf86OutputPtr output = config->output[i];
7544 
7545 			for (j = 0; j < ARRAY_SIZE(user_overrides); j++) {
7546 				if (xf86GetOptValString(output->options, user_overrides[j])) {
7547 					DBG(("%s: user placement [%d] for %s\n",
7548 					     __FUNCTION__,
7549 					     user_overrides[j],
7550 					     output->name));
7551 					return false;
7552 				}
7553 			}
7554 		}
7555 	}
7556 
7557 	/* Copy the existing modes on each CRTCs */
7558 	crtc_active = crtc_enabled = 0;
7559 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
7560 		xf86CrtcPtr crtc = config->crtc[i];
7561 		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
7562 		struct drm_mode_crtc mode;
7563 
7564 		crtc->enabled = FALSE;
7565 		crtc->desiredMode.status = MODE_NOMODE;
7566 
7567 		crtc_init_gamma(crtc);
7568 
7569 		/* Retrieve the current mode */
7570 		VG_CLEAR(mode);
7571 		mode.crtc_id = __sna_crtc_id(sna_crtc);
7572 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode))
7573 			continue;
7574 
7575 		DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__,
7576 		     __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
7577 		     mode.mode_valid && mode.mode.clock));
7578 
7579 		if (!mode.mode_valid || mode.mode.clock == 0)
7580 			continue;
7581 
7582 		mode_from_kmode(scrn, &mode.mode, &crtc->desiredMode);
7583 		crtc->desiredRotation = sna_crtc->primary.rotation.current;
7584 		crtc->desiredX = mode.x;
7585 		crtc->desiredY = mode.y;
7586 		crtc->desiredTransformPresent = FALSE;
7587 		crtc_active++;
7588 	}
7589 
7590 	/* Reconstruct outputs pointing to active CRTC */
7591 	for (i = 0; i < sna->mode.num_real_output; i++) {
7592 		xf86OutputPtr output = config->output[i];
7593 		uint32_t crtc_id;
7594 
7595 		assert(to_sna_output(output));
7596 
7597 		crtc_id = (uintptr_t)output->crtc;
7598 		output->crtc = NULL;
7599 		output->status = XF86OutputStatusUnknown;
7600 		if (sna->flags & SNA_IS_SLAVED)
7601 			continue;
7602 
7603 		if (crtc_id == 0) {
7604 			DBG(("%s: not using output %s, disconnected\n",
7605 			     __FUNCTION__, output->name));
7606 			continue;
7607 		}
7608 
7609 		if (xf86ReturnOptValBool(output->options, OPTION_DISABLE, 0)) {
7610 			DBG(("%s: not using output %s, manually disabled\n",
7611 			     __FUNCTION__, output->name));
7612 			continue;
7613 		}
7614 
7615 		for (j = 0; j < sna->mode.num_real_crtc; j++) {
7616 			xf86CrtcPtr crtc = config->crtc[j];
7617 
7618 			assert(to_sna_crtc(crtc));
7619 			if (sna_crtc_id(crtc) != crtc_id)
7620 				continue;
7621 
7622 			if (crtc->desiredMode.status == MODE_OK) {
7623 				DisplayModePtr M;
7624 				const char *pref;
7625 
7626 				pref = preferred_mode(output);
7627 				if (pref && strcmp(pref, crtc->desiredMode.name)) {
7628 					DBG(("%s: output %s user requests a different preferred mode %s, found %s\n",
7629 					     __FUNCTION__, output->name, pref, crtc->desiredMode.name));
7630 					return false;
7631 				}
7632 
7633 				xf86DrvMsg(scrn->scrnIndex, X_PROBED,
7634 					   "Output %s using initial mode %s on pipe %d\n",
7635 					   output->name,
7636 					   crtc->desiredMode.name,
7637 					   sna_crtc_pipe(crtc));
7638 
7639 				output->crtc = crtc;
7640 				output->status = XF86OutputStatusConnected;
7641 				crtc->enabled = TRUE;
7642 				crtc_enabled++;
7643 
7644 				output_set_gamma(output, crtc);
7645 
7646 				if (output->conf_monitor) {
7647 					output->mm_width = output->conf_monitor->mon_width;
7648 					output->mm_height = output->conf_monitor->mon_height;
7649 				}
7650 
7651 #if 0
7652 				sna_output_attach_edid(output);
7653 				sna_output_attach_tile(output);
7654 #endif
7655 
7656 				if (output->mm_width == 0 || output->mm_height == 0) {
7657 					output->mm_height = (crtc->desiredMode.VDisplay * 254) / (10*DEFAULT_DPI);
7658 					output->mm_width = (crtc->desiredMode.HDisplay * 254) / (10*DEFAULT_DPI);
7659 				}
7660 
7661 				M = calloc(1, sizeof(DisplayModeRec));
7662 				if (M) {
7663 					*M = crtc->desiredMode;
7664 					M->name = strdup(M->name);
7665 					output->probed_modes =
7666 						xf86ModesAdd(output->probed_modes, M);
7667 				}
7668 			}
7669 
7670 			break;
7671 		}
7672 
7673 		if (j == sna->mode.num_real_crtc) {
7674 			/* Can not find the earlier associated CRTC, bail */
7675 			DBG(("%s: existing setup conflicts with output assignment (Zaphod), reprobing\n",
7676 			     __FUNCTION__));
7677 			return false;
7678 		}
7679 	}
7680 
7681 	if (crtc_active != crtc_enabled) {
7682 		DBG(("%s: only enabled %d out of %d active CRTC, forcing a reconfigure\n",
7683 		     __FUNCTION__, crtc_enabled, crtc_active));
7684 		return false;
7685 	}
7686 
7687 	width = height = 0;
7688 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
7689 		xf86CrtcPtr crtc = config->crtc[i];
7690 		int w, h;
7691 
7692 		if (!crtc->enabled)
7693 			continue;
7694 
7695 		w = crtc->desiredX + crtc->desiredMode.HDisplay;
7696 		if (w > width)
7697 			width = w;
7698 		h = crtc->desiredY + crtc->desiredMode.VDisplay;
7699 		if (h > height)
7700 			height = h;
7701 	}
7702 
7703 	/* Prefer the native panel size if any */
7704 	if (!width || !height) {
7705 		for (i = 0; i < sna->mode.num_real_output; i++) {
7706 			xf86OutputPtr output = config->output[i];
7707 			struct sna_output *sna_output = to_sna_output(output);
7708 
7709 			if (!sna_output->is_panel)
7710 				continue;
7711 
7712 			DBG(("%s: querying panel '%s' for preferred unattached size\n",
7713 			     __FUNCTION__, output->name));
7714 
7715 			if (sna_output_detect(output) != XF86OutputStatusConnected)
7716 				continue;
7717 
7718 			if (sna_output->num_modes == 0)
7719 				continue;
7720 
7721 			width  = sna_output->modes[0].hdisplay;
7722 			height = sna_output->modes[0].vdisplay;
7723 
7724 			DBG(("%s: panel '%s' is %dx%d\n",
7725 			     __FUNCTION__, output->name, width, height));
7726 			break;
7727 		}
7728 	}
7729 
7730 	if (!width || !height) {
7731 		width = 1024;
7732 		height = 768;
7733 	}
7734 
7735 	scrn->display->frameX0 = 0;
7736 	scrn->display->frameY0 = 0;
7737 	scrn->display->virtualX = width;
7738 	scrn->display->virtualY = height;
7739 
7740 	scrn->virtualX = width;
7741 	scrn->virtualY = height;
7742 
7743 	xf86SetScrnInfoModes(sna->scrn);
7744 	DBG(("%s: SetScrnInfoModes = %p\n", __FUNCTION__, scrn->modes));
7745 	return scrn->modes != NULL;
7746 }
7747 
7748 static void
sanitize_outputs(struct sna * sna)7749 sanitize_outputs(struct sna *sna)
7750 {
7751 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
7752 	int i;
7753 
7754 	for (i = 0; i < config->num_output; i++)
7755 		config->output[i]->crtc = NULL;
7756 }
7757 
has_flip(struct sna * sna)7758 static bool has_flip(struct sna *sna)
7759 {
7760 	drm_i915_getparam_t gp;
7761 	int v;
7762 
7763 	if (sna->flags & SNA_NO_FLIP)
7764 		return false;
7765 
7766 	v = 0;
7767 
7768 	VG_CLEAR(gp);
7769 	gp.param = I915_PARAM_HAS_PAGEFLIPPING;
7770 	gp.value = &v;
7771 
7772 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GETPARAM, &gp))
7773 		return false;
7774 
7775 	VG(VALGRIND_MAKE_MEM_DEFINED(&v, sizeof(v)));
7776 	return v > 0;
7777 }
7778 
has_flip__async(struct sna * sna)7779 static bool has_flip__async(struct sna *sna)
7780 {
7781 #define DRM_CAP_ASYNC_PAGE_FLIP 0x7
7782 	struct local_get_cap {
7783 		uint64_t name;
7784 		uint64_t value;
7785 	} cap = { .name = DRM_CAP_ASYNC_PAGE_FLIP, };
7786 
7787 	if (sna->flags & SNA_NO_FLIP)
7788 		return false;
7789 
7790 	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0)
7791 		return cap.value > 0;
7792 
7793 	return false;
7794 }
7795 
7796 static void
probe_capabilities(struct sna * sna)7797 probe_capabilities(struct sna *sna)
7798 {
7799 	sna->flags &= ~(SNA_HAS_FLIP | SNA_HAS_ASYNC_FLIP);
7800 	if (has_flip(sna))
7801 		sna->flags |= SNA_HAS_FLIP;
7802 	if (has_flip__async(sna) && (sna->flags & SNA_TEAR_FREE) == 0)
7803 		sna->flags |= SNA_HAS_ASYNC_FLIP;
7804 	DBG(("%s: page flips? %s, async? %s\n", __FUNCTION__,
7805 	     sna->flags & SNA_HAS_FLIP ? "enabled" : "disabled",
7806 	     sna->flags & SNA_HAS_ASYNC_FLIP ? "enabled" : "disabled"));
7807 }
7808 
7809 void
sna_crtc_config_notify(ScreenPtr screen)7810 sna_crtc_config_notify(ScreenPtr screen)
7811 {
7812 	struct sna *sna = to_sna_from_screen(screen);
7813 
7814 	DBG(("%s(dirty?=%d)\n", __FUNCTION__, sna->mode.dirty));
7815 	if (!sna->mode.dirty)
7816 		return;
7817 
7818 	if (disable_unused_crtc(sna)) {
7819 		/* This will have recursed, so simply bail at this point */
7820 		assert(sna->mode.dirty == false);
7821 #ifdef RANDR_12_INTERFACE
7822 		xf86RandR12TellChanged(screen);
7823 #endif
7824 		return;
7825 	}
7826 
7827 	/* Flush any events completed by the modeset */
7828 	sna_mode_wakeup(sna);
7829 
7830 	update_flush_interval(sna);
7831 	sna->cursor.disable = false; /* Reset HW cursor until the next fail */
7832 	sna_cursors_reload(sna);
7833 
7834 	probe_capabilities(sna);
7835 	sna_present_update(sna);
7836 
7837 	/* Allow TearFree to come back on when everything is off */
7838 	if (!sna->mode.front_active && sna->flags & SNA_WANT_TEAR_FREE) {
7839 		if ((sna->flags & SNA_TEAR_FREE) == 0)
7840 			DBG(("%s: enable TearFree next modeset\n",
7841 			     __FUNCTION__));
7842 
7843 		sna->flags |= SNA_TEAR_FREE;
7844 	}
7845 
7846 	sna->mode.dirty = false;
7847 }
7848 
7849 #if HAS_PIXMAP_SHARING
7850 #define sna_setup_provider(scrn) xf86ProviderSetup(scrn, NULL, "Intel")
7851 #else
7852 #define sna_setup_provider(scrn)
7853 #endif
7854 
sna_mode_pre_init(ScrnInfoPtr scrn,struct sna * sna)7855 bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
7856 {
7857 	drmModeResPtr res;
7858 	int num_fake = 0;
7859 	int i;
7860 
7861 	if (sna->flags & SNA_IS_HOSTED) {
7862 		sna_setup_provider(scrn);
7863 		return true;
7864 	}
7865 
7866 	probe_capabilities(sna);
7867 	sna->mode.hidden = !isGPU(scrn); /* No DPMS passthrough */
7868 
7869 	if (!xf86GetOptValInteger(sna->Options, OPTION_VIRTUAL, &num_fake))
7870 		num_fake = 1;
7871 
7872 	res = drmModeGetResources(sna->kgem.fd);
7873 	if (res &&
7874 	    (res->count_crtcs == 0 ||
7875 	     res->count_encoders == 0 ||
7876 	     res->count_connectors == 0)) {
7877 		drmModeFreeResources(res);
7878 		res = NULL;
7879 	}
7880 	if (res) {
7881 		xf86CrtcConfigPtr xf86_config;
7882 
7883 		DBG(("%s: found %d CRTC, %d encoders, %d connectors\n",
7884 		     __FUNCTION__, res->count_crtcs, res->count_encoders, res->count_connectors));
7885 
7886 		assert(res->count_crtcs);
7887 		assert(res->count_connectors);
7888 
7889 		xf86CrtcConfigInit(scrn, &sna_mode_funcs);
7890 
7891 		xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
7892 		xf86_config->xf86_crtc_notify = sna_crtc_config_notify;
7893 		xf86_config->compat_output = 0;
7894 
7895 		for (i = 0; i < res->count_crtcs; i++)
7896 			if (!sna_crtc_add(scrn, res->crtcs[i]))
7897 				return false;
7898 
7899 		sna->mode.num_real_crtc = xf86_config->num_crtc;
7900 
7901 		sna->mode.num_real_encoder = res->count_encoders;
7902 		sna->mode.encoders = res->encoders;
7903 		res->encoders = NULL;
7904 
7905 		for (i = 0; i < res->count_connectors; i++)
7906 			if (sna_output_add(sna, res->connectors[i], 0) < 0)
7907 				return false;
7908 
7909 		sna->mode.num_real_output = xf86_config->num_output;
7910 
7911 		sna->mode.max_crtc_width  = res->max_width;
7912 		sna->mode.max_crtc_height = res->max_height;
7913 
7914 		RegionEmpty(&sna->mode.shadow_region);
7915 		RegionEmpty(&sna->mode.shadow_cancel);
7916 		list_init(&sna->mode.shadow_crtc);
7917 
7918 		drmModeFreeResources(res);
7919 
7920 		sna_cursor_pre_init(sna);
7921 		sna_backlight_pre_init(sna);
7922 
7923 		set_size_range(sna);
7924 	} else {
7925 		if (num_fake == 0)
7926 			num_fake = 1;
7927 	}
7928 
7929 	if (!sna_mode_fake_init(sna, num_fake))
7930 		return false;
7931 
7932 	sna->mode.shadow_size = 256;
7933 	sna->mode.shadow_events = malloc(sna->mode.shadow_size * sizeof(struct drm_event_vblank));
7934 	if (!sna->mode.shadow_events)
7935 		return false;
7936 
7937 	if (!sna_probe_initial_configuration(sna)) {
7938 		xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
7939 
7940 		sanitize_outputs(sna);
7941 		if (config->num_crtc && config->num_output) {
7942 			if (!xf86ReturnOptValBool(config->output[0]->options,
7943 						  OPTION_PRIMARY, FALSE))
7944 				sort_config_outputs(sna);
7945 			xf86InitialConfiguration(scrn, TRUE);
7946 		}
7947 	}
7948 	sort_config_outputs(sna);
7949 
7950 	sna_setup_provider(scrn);
7951 	return scrn->modes != NULL;
7952 }
7953 
7954 bool
sna_mode_wants_tear_free(struct sna * sna)7955 sna_mode_wants_tear_free(struct sna *sna)
7956 {
7957 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
7958 	bool found = false;
7959 	FILE *file;
7960 	int i;
7961 
7962 	file = fopen("/sys/module/i915/parameters/enable_fbc", "r");
7963 	if (file) {
7964 		int fbc_enabled = 0;
7965 		int value;
7966 
7967 		if (fscanf(file, "%d", &value) == 1)
7968 			fbc_enabled = value > 0;
7969 		fclose(file);
7970 
7971 		DBG(("%s: module parameter 'enable_fbc' enabled? %d\n",
7972 		     __FUNCTION__, fbc_enabled));
7973 
7974 		if (fbc_enabled)
7975 			return true;
7976 	}
7977 
7978 	for (i = 0; i < sna->mode.num_real_output; i++) {
7979 		struct sna_output *output = to_sna_output(config->output[i]);
7980 		int id = find_property(sna, output, "Panel Self-Refresh");
7981 		if (id == -1)
7982 			continue;
7983 
7984 		found = true;
7985 		if (output->prop_values[id] != -1) {
7986 			DBG(("%s: Panel Self-Refresh detected on %s\n",
7987 			     __FUNCTION__, config->output[i]->name));
7988 			return true;
7989 		}
7990 	}
7991 
7992 	if (!found) {
7993 		file = fopen("/sys/module/i915/parameters/enable_psr", "r");
7994 		if (file) {
7995 			int psr_enabled = 0;
7996 			int value;
7997 
7998 			if (fscanf(file, "%d", &value) == 1)
7999 				psr_enabled = value > 0;
8000 			fclose(file);
8001 
8002 			DBG(("%s: module parameter 'enable_psr' enabled? %d\n",
8003 			     __FUNCTION__, psr_enabled));
8004 
8005 			if (psr_enabled)
8006 				return true;
8007 		}
8008 	}
8009 
8010 	return false;
8011 }
8012 
8013 void
sna_mode_set_primary(struct sna * sna)8014 sna_mode_set_primary(struct sna *sna)
8015 {
8016 #ifdef RANDR_12_INTERFACE
8017 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8018 	rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn));
8019 	int i;
8020 
8021 	if (rr == NULL || rr->primaryOutput)
8022 		return;
8023 
8024 	for (i = 0; i < sna->mode.num_real_output; i++) {
8025 		xf86OutputPtr output = config->output[i];
8026 
8027 		if (!xf86ReturnOptValBool(output->options, OPTION_PRIMARY, FALSE))
8028 			continue;
8029 
8030 		DBG(("%s: setting PrimaryOutput %s\n", __FUNCTION__, output->name));
8031 		rr->primaryOutput = output->randr_output;
8032 		RROutputChanged(rr->primaryOutput, FALSE);
8033 		rr->layoutChanged = TRUE;
8034 		break;
8035 	}
8036 #endif
8037 }
8038 
8039 bool
sna_mode_disable(struct sna * sna)8040 sna_mode_disable(struct sna *sna)
8041 {
8042 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8043 	int i;
8044 
8045 	if (sna->flags & SNA_IS_HOSTED)
8046 		return false;
8047 
8048 	if (!sna->scrn->vtSema)
8049 		return false;
8050 
8051 	sna_disable_cursors(sna->scrn);
8052 	for (i = 0; i < sna->mode.num_real_crtc; i++)
8053 		sna_crtc_disable(config->crtc[i], false);
8054 	assert(sna->mode.front_active == 0);
8055 
8056 	sna_mode_wakeup(sna);
8057 	kgem_clean_scanout_cache(&sna->kgem);
8058 	return true;
8059 }
8060 
8061 void
sna_mode_enable(struct sna * sna)8062 sna_mode_enable(struct sna *sna)
8063 {
8064 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8065 	int i;
8066 
8067 	DBG(("%s\n", __FUNCTION__));
8068 
8069 	if (sna->flags & SNA_IS_HOSTED)
8070 		return;
8071 
8072 	if (!sna->scrn->vtSema)
8073 		return;
8074 
8075 	if (sna->mode.hidden) {
8076 		DBG(("%s: hidden outputs\n", __FUNCTION__));
8077 		return;
8078 	}
8079 
8080 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
8081 		xf86CrtcPtr crtc = config->crtc[i];
8082 
8083 		DBG(("%s: crtc[%d].enabled?=%d\n", __FUNCTION__, i, crtc->enabled));
8084 		assert(to_sna_crtc(crtc) != NULL);
8085 		if (!crtc->enabled)
8086 			continue;
8087 
8088 		if (crtc->mode.Clock == 0)
8089 			continue;
8090 
8091 		__sna_crtc_set_mode(crtc);
8092 	}
8093 
8094 	update_flush_interval(sna);
8095 	sna_cursors_reload(sna);
8096 	sna->mode.dirty = false;
8097 }
8098 
sna_randr_close(struct sna * sna)8099 static void sna_randr_close(struct sna *sna)
8100 {
8101 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8102 	int n;
8103 
8104 	/* The RR structs are freed early during CloseScreen as they
8105 	 * are tracked as Resources. However, we may be tempted to
8106 	 * access them during shutdown so decouple them now.
8107 	 */
8108 	  for (n = 0; n < config->num_output; n++)
8109 		  config->output[n]->randr_output = NULL;
8110 
8111 	  for (n = 0; n < config->num_crtc; n++)
8112 		  config->crtc[n]->randr_crtc = NULL;
8113 }
8114 
8115 void
sna_mode_close(struct sna * sna)8116 sna_mode_close(struct sna *sna)
8117 {
8118 	sna_randr_close(sna);
8119 	sna_mode_wakeup(sna);
8120 
8121 	if (sna->flags & SNA_IS_HOSTED)
8122 		return;
8123 
8124 	sna_mode_reset(sna);
8125 
8126 	sna_cursor_close(sna);
8127 	sna_cursors_fini(sna);
8128 
8129 	sna_backlight_close(sna);
8130 	sna->mode.dirty = false;
8131 }
8132 
8133 void
sna_mode_fini(struct sna * sna)8134 sna_mode_fini(struct sna *sna)
8135 {
8136 	free(sna->mode.encoders);
8137 }
8138 
sna_box_intersect(BoxPtr r,const BoxRec * a,const BoxRec * b)8139 static bool sna_box_intersect(BoxPtr r, const BoxRec *a, const BoxRec *b)
8140 {
8141 	r->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
8142 	r->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
8143 	if (r->x1 >= r->x2)
8144 		return false;
8145 
8146 	r->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
8147 	r->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
8148 	DBG(("%s: (%d, %d), (%d, %d) intersect (%d, %d), (%d, %d) = (%d, %d), (%d, %d)\n",
8149 	     __FUNCTION__,
8150 	     a->x1, a->y1, a->x2, a->y2,
8151 	     b->x1, b->y1, b->x2, b->y2,
8152 	     r->x1, r->y1, r->x2, r->y2));
8153 	if (r->y1 >= r->y2)
8154 		return false;
8155 
8156 	return true;
8157 }
8158 
sna_box_area(const BoxRec * box)8159 static int sna_box_area(const BoxRec *box)
8160 {
8161 	return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1);
8162 }
8163 
8164 /*
8165  * Return the crtc covering 'box'. If two crtcs cover a portion of
8166  * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
8167  * with greater coverage
8168  */
8169 xf86CrtcPtr
sna_covering_crtc(struct sna * sna,const BoxRec * box,xf86CrtcPtr desired)8170 sna_covering_crtc(struct sna *sna, const BoxRec *box, xf86CrtcPtr desired)
8171 {
8172 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8173 	xf86CrtcPtr best_crtc = NULL;
8174 	int best_coverage = -1, c;
8175 
8176 	if (sna->flags & SNA_IS_HOSTED)
8177 		return NULL;
8178 
8179 	/* If we do not own the VT, we do not own the CRTC either */
8180 	if (!sna->scrn->vtSema) {
8181 		DBG(("%s: none, VT switched\n", __FUNCTION__));
8182 		return NULL;
8183 	}
8184 
8185 	if (sna->mode.hidden) {
8186 		DBG(("%s: none, hidden outputs\n", __FUNCTION__));
8187 		return NULL;
8188 	}
8189 
8190 	DBG(("%s for box=(%d, %d), (%d, %d)\n",
8191 	     __FUNCTION__, box->x1, box->y1, box->x2, box->y2));
8192 
8193 	if (desired == NULL) {
8194 		ScreenPtr screen = xf86ScrnToScreen(sna->scrn);
8195 		rrScrPrivPtr rr = rrGetScrPriv(screen);
8196 		if (rr && rr->primaryOutput && rr->primaryOutput->pScreen == screen) {
8197 			xf86OutputPtr output = rr->primaryOutput->devPrivate;
8198 			DBG(("%s: have PrimaryOutput? %d marking as desired\n", __FUNCTION__, output->crtc != NULL));
8199 			desired = output->crtc;
8200 		}
8201 		assert(!desired || desired->scrn == sna->scrn);
8202 	}
8203 	if (desired && to_sna_crtc(desired) && to_sna_crtc(desired)->bo) {
8204 		BoxRec cover_box;
8205 		if (sna_box_intersect(&cover_box, &desired->bounds, box)) {
8206 			DBG(("%s: box overlaps desired crtc: (%d, %d), (%d, %d)\n",
8207 			     __FUNCTION__,
8208 			     cover_box.x1, cover_box.y1,
8209 			     cover_box.x2, cover_box.y2));
8210 			return desired;
8211 		}
8212 		best_crtc = desired;
8213 		best_coverage = 0;
8214 	}
8215 
8216 	for (c = 0; c < sna->mode.num_real_crtc; c++) {
8217 		xf86CrtcPtr crtc = config->crtc[c];
8218 		BoxRec cover_box;
8219 		int coverage;
8220 
8221 		assert(to_sna_crtc(crtc));
8222 
8223 		/* If the CRTC is off, treat it as not covering */
8224 		if (to_sna_crtc(crtc)->bo == NULL) {
8225 			DBG(("%s: crtc %d off, skipping\n", __FUNCTION__, c));
8226 			continue;
8227 		}
8228 
8229 		DBG(("%s: crtc %d: (%d, %d), (%d, %d)\n",
8230 		     __FUNCTION__, c,
8231 		     crtc->bounds.x1, crtc->bounds.y1,
8232 		     crtc->bounds.x2, crtc->bounds.y2));
8233 		if (!memcmp(box, &crtc->bounds, sizeof(*box))) {
8234 			DBG(("%s: box exactly matches crtc [%d]\n",
8235 			     __FUNCTION__, c));
8236 			return crtc;
8237 		}
8238 
8239 		coverage = 0;
8240 		if (sna_box_intersect(&cover_box, &crtc->bounds, box))
8241 			coverage = sna_box_area(&cover_box);
8242 
8243 		DBG(("%s: box instersects (%d, %d), (%d, %d) of crtc %d\n",
8244 		     __FUNCTION__,
8245 		     cover_box.x1, cover_box.y1,
8246 		     cover_box.x2, cover_box.y2,
8247 		     c));
8248 
8249 		DBG(("%s: box covers %d of crtc %d\n",
8250 		     __FUNCTION__, coverage, c));
8251 		if (coverage > best_coverage) {
8252 			best_crtc = crtc;
8253 			best_coverage = coverage;
8254 		}
8255 	}
8256 	DBG(("%s: best crtc = %p, coverage = %d\n",
8257 	     __FUNCTION__, best_crtc, best_coverage));
8258 	return best_crtc;
8259 }
8260 
first_active_crtc(struct sna * sna)8261 static xf86CrtcPtr first_active_crtc(struct sna *sna)
8262 {
8263 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8264 	int n;
8265 
8266 	for (n = 0; n < sna->mode.num_real_crtc; n++) {
8267 		xf86CrtcPtr crtc = config->crtc[n];
8268 		if (to_sna_crtc(crtc)->bo)
8269 			return crtc;
8270 	}
8271 
8272 	/* No active, use the first as a placeholder */
8273 	if (sna->mode.num_real_crtc)
8274 		return config->crtc[0];
8275 
8276 	return NULL;
8277 }
8278 
sna_primary_crtc(struct sna * sna)8279 xf86CrtcPtr sna_primary_crtc(struct sna *sna)
8280 {
8281 	rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn));
8282 	if (rr && rr->primaryOutput) {
8283 		xf86OutputPtr output = rr->primaryOutput->devPrivate;
8284 		if (output->crtc &&
8285 		    output->scrn == sna->scrn &&
8286 		    to_sna_crtc(output->crtc))
8287 			return output->crtc;
8288 	}
8289 
8290 	return first_active_crtc(sna);
8291 }
8292 
8293 #define MI_LOAD_REGISTER_IMM			(0x22<<23)
8294 
sna_emit_wait_for_scanline_hsw(struct sna * sna,xf86CrtcPtr crtc,int pipe,int y1,int y2,bool full_height)8295 static bool sna_emit_wait_for_scanline_hsw(struct sna *sna,
8296 					   xf86CrtcPtr crtc,
8297 					   int pipe, int y1, int y2,
8298 					   bool full_height)
8299 {
8300 	uint32_t event;
8301 	uint32_t *b;
8302 
8303 	if (!sna->kgem.has_secure_batches)
8304 		return false;
8305 
8306 	b = kgem_get_batch(&sna->kgem);
8307 	sna->kgem.nbatch += 17;
8308 
8309 	switch (pipe) {
8310 	default: assert(0); /* fall through */
8311 	case 0: event = 1 << 0; break;
8312 	case 1: event = 1 << 8; break;
8313 	case 2: event = 1 << 14; break;
8314 	}
8315 
8316 	b[0] = MI_LOAD_REGISTER_IMM | 1;
8317 	b[1] = 0x44050; /* DERRMR */
8318 	b[2] = ~event;
8319 	b[3] = MI_LOAD_REGISTER_IMM | 1;
8320 	b[4] = 0xa188; /* FORCEWAKE_MT */
8321 	b[5] = 2 << 16 | 2;
8322 
8323 	/* The documentation says that the LOAD_SCAN_LINES command
8324 	 * always comes in pairs. Don't ask me why. */
8325 	switch (pipe) {
8326 	default: assert(0); /* fall through */
8327 	case 0: event = 0 << 19; break;
8328 	case 1: event = 1 << 19; break;
8329 	case 2: event = 4 << 19; break;
8330 	}
8331 	b[8] = b[6] = MI_LOAD_SCAN_LINES_INCL | event;
8332 	b[9] = b[7] = (y1 << 16) | (y2-1);
8333 
8334 	switch (pipe) {
8335 	default: assert(0); /* fall through */
8336 	case 0: event = 1 << 0; break;
8337 	case 1: event = 1 << 8; break;
8338 	case 2: event = 1 << 14; break;
8339 	}
8340 	b[10] = MI_WAIT_FOR_EVENT | event;
8341 
8342 	b[11] = MI_LOAD_REGISTER_IMM | 1;
8343 	b[12] = 0xa188; /* FORCEWAKE_MT */
8344 	b[13] = 2 << 16;
8345 	b[14] = MI_LOAD_REGISTER_IMM | 1;
8346 	b[15] = 0x44050; /* DERRMR */
8347 	b[16] = ~0;
8348 
8349 	sna->kgem.batch_flags |= I915_EXEC_SECURE;
8350 	return true;
8351 }
8352 
sna_emit_wait_for_scanline_ivb(struct sna * sna,xf86CrtcPtr crtc,int pipe,int y1,int y2,bool full_height)8353 static bool sna_emit_wait_for_scanline_ivb(struct sna *sna,
8354 					   xf86CrtcPtr crtc,
8355 					   int pipe, int y1, int y2,
8356 					   bool full_height)
8357 {
8358 	uint32_t event, *b;
8359 
8360 	if (!sna->kgem.has_secure_batches)
8361 		return false;
8362 
8363 	assert(y1 >= 0);
8364 	assert(y2 > y1);
8365 	assert(sna->kgem.mode);
8366 
8367 	/* Always program one less than the desired value */
8368 	if (--y1 < 0)
8369 		y1 = crtc->bounds.y2;
8370 	y2--;
8371 
8372 	switch (pipe) {
8373 	default:
8374 		assert(0);
8375 		/* fall through */
8376 	case 0:
8377 		event = 1 << (full_height ? 3 : 0);
8378 		break;
8379 	case 1:
8380 		event = 1 << (full_height ? 11 : 8);
8381 		break;
8382 	case 2:
8383 		event = 1 << (full_height ? 21 : 14);
8384 		break;
8385 	}
8386 
8387 	b = kgem_get_batch(&sna->kgem);
8388 
8389 	/* Both the LRI and WAIT_FOR_EVENT must be in the same cacheline */
8390 	if (((sna->kgem.nbatch + 6) >> 4) != (sna->kgem.nbatch + 10) >> 4) {
8391 		int dw = sna->kgem.nbatch + 6;
8392 		dw = ALIGN(dw, 16) - dw;
8393 		while (dw--)
8394 			*b++ = MI_NOOP;
8395 	}
8396 
8397 	b[0] = MI_LOAD_REGISTER_IMM | 1;
8398 	b[1] = 0x44050; /* DERRMR */
8399 	b[2] = ~event;
8400 	b[3] = MI_LOAD_REGISTER_IMM | 1;
8401 	b[4] = 0xa188; /* FORCEWAKE_MT */
8402 	b[5] = 2 << 16 | 2;
8403 	b[6] = MI_LOAD_REGISTER_IMM | 1;
8404 	b[7] = 0x70068 + 0x1000 * pipe;
8405 	b[8] = (1 << 31) | (1 << 30) | (y1 << 16) | y2;
8406 	b[9] = MI_WAIT_FOR_EVENT | event;
8407 	b[10] = MI_LOAD_REGISTER_IMM | 1;
8408 	b[11] = 0xa188; /* FORCEWAKE_MT */
8409 	b[12] = 2 << 16;
8410 	b[13] = MI_LOAD_REGISTER_IMM | 1;
8411 	b[14] = 0x44050; /* DERRMR */
8412 	b[15] = ~0;
8413 
8414 	sna->kgem.nbatch = b - sna->kgem.batch + 16;
8415 
8416 	sna->kgem.batch_flags |= I915_EXEC_SECURE;
8417 	return true;
8418 }
8419 
sna_emit_wait_for_scanline_gen6(struct sna * sna,xf86CrtcPtr crtc,int pipe,int y1,int y2,bool full_height)8420 static bool sna_emit_wait_for_scanline_gen6(struct sna *sna,
8421 					    xf86CrtcPtr crtc,
8422 					    int pipe, int y1, int y2,
8423 					    bool full_height)
8424 {
8425 	uint32_t *b;
8426 	uint32_t event;
8427 
8428 	if (!sna->kgem.has_secure_batches)
8429 		return false;
8430 
8431 	assert(y1 >= 0);
8432 	assert(y2 > y1);
8433 	assert(sna->kgem.mode == KGEM_RENDER);
8434 
8435 	/* Always program one less than the desired value */
8436 	if (--y1 < 0)
8437 		y1 = crtc->bounds.y2;
8438 	y2--;
8439 
8440 	/* The scanline granularity is 3 bits */
8441 	y1 &= ~7;
8442 	y2 &= ~7;
8443 	if (y2 == y1)
8444 		return false;
8445 
8446 	event = 1 << (3*full_height + pipe*8);
8447 
8448 	b = kgem_get_batch(&sna->kgem);
8449 	sna->kgem.nbatch += 16;
8450 
8451 	b[0] = MI_LOAD_REGISTER_IMM | 1;
8452 	b[1] = 0x44050; /* DERRMR */
8453 	b[2] = ~event;
8454 	b[3] = MI_LOAD_REGISTER_IMM | 1;
8455 	b[4] = 0x4f100; /* magic */
8456 	b[5] = (1 << 31) | (1 << 30) | pipe << 29 | (y1 << 16) | y2;
8457 	b[6] = MI_LOAD_REGISTER_IMM | 1;
8458 	b[7] = 0x2050; /* PSMI_CTL(rcs) */
8459 	b[8] = 1 << 16 | 1;
8460 	b[9] = MI_WAIT_FOR_EVENT | event;
8461 	b[10] = MI_LOAD_REGISTER_IMM | 1;
8462 	b[11] = 0x2050; /* PSMI_CTL(rcs) */
8463 	b[12] = 1 << 16;
8464 	b[13] = MI_LOAD_REGISTER_IMM | 1;
8465 	b[14] = 0x44050; /* DERRMR */
8466 	b[15] = ~0;
8467 
8468 	sna->kgem.batch_flags |= I915_EXEC_SECURE;
8469 	return true;
8470 }
8471 
sna_emit_wait_for_scanline_gen4(struct sna * sna,xf86CrtcPtr crtc,int pipe,int y1,int y2,bool full_height)8472 static bool sna_emit_wait_for_scanline_gen4(struct sna *sna,
8473 					    xf86CrtcPtr crtc,
8474 					    int pipe, int y1, int y2,
8475 					    bool full_height)
8476 {
8477 	uint32_t event;
8478 	uint32_t *b;
8479 
8480 	if (pipe == 0) {
8481 		if (full_height)
8482 			event = MI_WAIT_FOR_PIPEA_SVBLANK;
8483 		else
8484 			event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
8485 	} else {
8486 		if (full_height)
8487 			event = MI_WAIT_FOR_PIPEB_SVBLANK;
8488 		else
8489 			event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
8490 	}
8491 
8492 	b = kgem_get_batch(&sna->kgem);
8493 	sna->kgem.nbatch += 5;
8494 
8495 	/* The documentation says that the LOAD_SCAN_LINES command
8496 	 * always comes in pairs. Don't ask me why. */
8497 	b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20;
8498 	b[3] = b[1] = (y1 << 16) | (y2-1);
8499 	b[4] = MI_WAIT_FOR_EVENT | event;
8500 
8501 	return true;
8502 }
8503 
sna_emit_wait_for_scanline_gen2(struct sna * sna,xf86CrtcPtr crtc,int pipe,int y1,int y2,bool full_height)8504 static bool sna_emit_wait_for_scanline_gen2(struct sna *sna,
8505 					    xf86CrtcPtr crtc,
8506 					    int pipe, int y1, int y2,
8507 					    bool full_height)
8508 {
8509 	uint32_t *b;
8510 
8511 	/*
8512 	 * Pre-965 doesn't have SVBLANK, so we need a bit
8513 	 * of extra time for the blitter to start up and
8514 	 * do its job for a full height blit
8515 	 */
8516 	if (full_height)
8517 		y2 -= 2;
8518 
8519 	b = kgem_get_batch(&sna->kgem);
8520 	sna->kgem.nbatch += 5;
8521 
8522 	/* The documentation says that the LOAD_SCAN_LINES command
8523 	 * always comes in pairs. Don't ask me why. */
8524 	b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20;
8525 	b[3] = b[1] = (y1 << 16) | (y2-1);
8526 	b[4] = MI_WAIT_FOR_EVENT | 1 << (1 + 4*pipe);
8527 
8528 	return true;
8529 }
8530 
8531 bool
sna_wait_for_scanline(struct sna * sna,PixmapPtr pixmap,xf86CrtcPtr crtc,const BoxRec * clip)8532 sna_wait_for_scanline(struct sna *sna,
8533 		      PixmapPtr pixmap,
8534 		      xf86CrtcPtr crtc,
8535 		      const BoxRec *clip)
8536 {
8537 	bool full_height;
8538 	int y1, y2, pipe;
8539 	bool ret;
8540 
8541 	assert(crtc != NULL);
8542 	assert(to_sna_crtc(crtc) != NULL);
8543 	assert(to_sna_crtc(crtc)->bo != NULL);
8544 	assert(pixmap == sna->front);
8545 
8546 	if (sna->flags & SNA_NO_VSYNC)
8547 		return false;
8548 
8549 	/*
8550 	 * Make sure we don't wait for a scanline that will
8551 	 * never occur
8552 	 */
8553 	y1 = clip->y1 - crtc->bounds.y1;
8554 	if (y1 < 0)
8555 		y1 = 0;
8556 	y2 = clip->y2 - crtc->bounds.y1;
8557 	if (y2 > crtc->bounds.y2 - crtc->bounds.y1)
8558 		y2 = crtc->bounds.y2 - crtc->bounds.y1;
8559 	DBG(("%s: clipped range = %d, %d\n", __FUNCTION__, y1, y2));
8560 	if (y2 <= y1 + 4)
8561 		return false;
8562 
8563 	full_height = y1 == 0 && y2 == crtc->bounds.y2 - crtc->bounds.y1;
8564 
8565 	if (crtc->mode.Flags & V_INTERLACE) {
8566 		/* DSL count field lines */
8567 		y1 /= 2;
8568 		y2 /= 2;
8569 	}
8570 
8571 	pipe = sna_crtc_pipe(crtc);
8572 	DBG(("%s: pipe=%d, y1=%d, y2=%d, full_height?=%d\n",
8573 	     __FUNCTION__, pipe, y1, y2, full_height));
8574 
8575 	if (sna->kgem.gen >= 0110)
8576 		ret = false;
8577 	else if (sna->kgem.gen == 0101)
8578 		ret = false; /* chv, vsync method unknown */
8579 	else if (sna->kgem.gen >= 075)
8580 		ret = sna_emit_wait_for_scanline_hsw(sna, crtc, pipe, y1, y2, full_height);
8581 	else if (sna->kgem.gen == 071)
8582 		ret = false; /* vlv, vsync method unknown */
8583 	else if (sna->kgem.gen >= 070)
8584 		ret = sna_emit_wait_for_scanline_ivb(sna, crtc, pipe, y1, y2, full_height);
8585 	else if (sna->kgem.gen >= 060)
8586 		ret =sna_emit_wait_for_scanline_gen6(sna, crtc, pipe, y1, y2, full_height);
8587 	else if (sna->kgem.gen >= 040)
8588 		ret = sna_emit_wait_for_scanline_gen4(sna, crtc, pipe, y1, y2, full_height);
8589 	else
8590 		ret = sna_emit_wait_for_scanline_gen2(sna, crtc, pipe, y1, y2, full_height);
8591 
8592 	return ret;
8593 }
8594 
sna_mode_shutdown_crtc(xf86CrtcPtr crtc)8595 static bool sna_mode_shutdown_crtc(xf86CrtcPtr crtc)
8596 {
8597 	struct sna *sna = to_sna(crtc->scrn);
8598 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
8599 	bool disabled = false;
8600 	int o;
8601 
8602 	xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
8603 		   "%s: invalid state found on pipe %d, disabling CRTC:%d\n",
8604 		   __FUNCTION__,
8605 		   __sna_crtc_pipe(to_sna_crtc(crtc)),
8606 		   __sna_crtc_id(to_sna_crtc(crtc)));
8607 	sna_crtc_disable(crtc, true);
8608 #if XF86_CRTC_VERSION >= 3
8609 	crtc->active = FALSE;
8610 #endif
8611 	if (crtc->enabled) {
8612 		crtc->enabled = FALSE;
8613 		disabled = true;
8614 	}
8615 
8616 	for (o = 0; o < sna->mode.num_real_output; o++) {
8617 		xf86OutputPtr output = config->output[o];
8618 
8619 		if (output->crtc != crtc)
8620 			continue;
8621 
8622 		output->funcs->dpms(output, DPMSModeOff);
8623 		output->crtc = NULL;
8624 	}
8625 
8626 	return disabled;
8627 }
8628 
8629 static bool
sna_mode_disable_secondary_planes(struct sna * sna)8630 sna_mode_disable_secondary_planes(struct sna *sna)
8631 {
8632 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8633 	bool disabled = false;
8634 	int c;
8635 
8636 	/* Disable all secondary planes on our CRTCs, just in case
8637 	 * other userspace left garbage in them.
8638 	 */
8639 	for (c = 0; c < sna->mode.num_real_crtc; c++) {
8640 		xf86CrtcPtr crtc = config->crtc[c];
8641 		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
8642 		struct plane *plane;
8643 
8644 		list_for_each_entry(plane, &sna_crtc->sprites, link) {
8645 			struct local_mode_get_plane p;
8646 			struct local_mode_set_plane s;
8647 
8648 			VG_CLEAR(p);
8649 			p.plane_id = plane->id;
8650 			p.count_format_types = 0;
8651 			if (drmIoctl(sna->kgem.fd,
8652 				     LOCAL_IOCTL_MODE_GETPLANE,
8653 				     &p))
8654 				continue;
8655 
8656 			if (p.fb_id == 0 || p.crtc_id == 0)
8657 				continue;
8658 
8659 			memset(&s, 0, sizeof(s));
8660 			s.plane_id = p.plane_id;
8661 			s.crtc_id = p.crtc_id;
8662 			if (drmIoctl(sna->kgem.fd,
8663 				     LOCAL_IOCTL_MODE_SETPLANE,
8664 				     &s))
8665 				disabled |= sna_mode_shutdown_crtc(crtc);
8666 		}
8667 	}
8668 
8669 	return disabled;
8670 }
8671 
sna_mode_check(struct sna * sna)8672 void sna_mode_check(struct sna *sna)
8673 {
8674 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8675 	bool disabled;
8676 	int c, o;
8677 
8678 	if (sna->flags & SNA_IS_HOSTED)
8679 		return;
8680 
8681 	DBG(("%s: hidden?=%d\n", __FUNCTION__, sna->mode.hidden));
8682 	if (sna->mode.hidden)
8683 		return;
8684 
8685 	disabled = sna_mode_disable_secondary_planes(sna);
8686 
8687 	/* Validate CRTC attachments and force consistency upon the kernel */
8688 	for (c = 0; c < sna->mode.num_real_crtc; c++) {
8689 		xf86CrtcPtr crtc = config->crtc[c];
8690 		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
8691 		struct drm_mode_crtc mode;
8692 		uint32_t expected[2];
8693 
8694 		assert(sna_crtc);
8695 
8696 #if XF86_CRTC_VERSION >= 3
8697 		assert(sna_crtc->bo == NULL || crtc->active);
8698 #endif
8699 		expected[0] = sna_crtc->bo ? fb_id(sna_crtc->bo) : 0;
8700 		expected[1] = sna_crtc->flip_bo ? fb_id(sna_crtc->flip_bo) : -1;
8701 
8702 		VG_CLEAR(mode);
8703 		mode.crtc_id = __sna_crtc_id(sna_crtc);
8704 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode))
8705 			continue;
8706 
8707 		DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=(%d or %d)\n",
8708 		     __FUNCTION__,
8709 		     mode.crtc_id, mode.mode_valid,
8710 		     mode.fb_id, expected[0], expected[1]));
8711 
8712 		if (mode.fb_id != expected[0] && mode.fb_id != expected[1])
8713 			disabled |= sna_mode_shutdown_crtc(crtc);
8714 	}
8715 
8716 	for (o = 0; o < config->num_output; o++) {
8717 		xf86OutputPtr output = config->output[o];
8718 		struct sna_output *sna_output;
8719 
8720 		if (output->crtc)
8721 			continue;
8722 
8723 		sna_output = to_sna_output(output);
8724 		if (sna_output == NULL)
8725 			continue;
8726 
8727 		sna_output->dpms_mode = DPMSModeOff;
8728 	}
8729 
8730 	update_flush_interval(sna);
8731 
8732 	if (disabled)
8733 		xf86RandR12TellChanged(xf86ScrnToScreen(sna->scrn));
8734 }
8735 
8736 static bool
sna_crtc_hide_planes(struct sna * sna,struct sna_crtc * crtc)8737 sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc)
8738 {
8739 	struct local_mode_set_plane s;
8740 	struct plane *plane;
8741 
8742 	if (crtc->primary.id == 0)
8743 		return false;
8744 
8745 	memset(&s, 0, sizeof(s));
8746 	s.plane_id = crtc->primary.id;
8747 	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
8748 		return false;
8749 
8750 	list_for_each_entry(plane, &crtc->sprites, link) {
8751 		s.plane_id = plane->id;
8752 		(void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s);
8753 	}
8754 
8755 	__sna_crtc_disable(sna, crtc);
8756 	return true;
8757 }
8758 
sna_mode_reset(struct sna * sna)8759 void sna_mode_reset(struct sna *sna)
8760 {
8761 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8762 	int i;
8763 
8764 	if (sna->flags & SNA_IS_HOSTED)
8765 		return;
8766 
8767 	DBG(("%s\n", __FUNCTION__));
8768 
8769 	sna_disable_cursors(sna->scrn);
8770 	for (i = 0; i < sna->mode.num_real_crtc; i++)
8771 		if (!sna_crtc_hide_planes(sna, to_sna_crtc(config->crtc[i])))
8772 			sna_crtc_disable(config->crtc[i], true);
8773 	assert(sna->mode.front_active == 0);
8774 
8775 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
8776 		struct sna_crtc *sna_crtc = to_sna_crtc(config->crtc[i]);
8777 		struct plane *plane;
8778 
8779 		assert(sna_crtc != NULL);
8780 
8781 		/* Force the rotation property to be reset on next use */
8782 		rotation_reset(&sna_crtc->primary);
8783 		list_for_each_entry(plane, &sna_crtc->sprites, link)
8784 			rotation_reset(plane);
8785 	}
8786 
8787 	/* VT switching, likely to be fbcon so make the backlight usable */
8788 	for (i = 0; i < sna->mode.num_real_output; i++) {
8789 		struct sna_output *sna_output = to_sna_output(config->output[i]);
8790 
8791 		assert(sna_output != NULL);
8792 		if (sna_output->dpms_mode != DPMSModeOff)
8793 			continue;
8794 
8795 		if (!sna_output->backlight.iface)
8796 			continue;
8797 
8798 		sna_output_backlight_set(sna_output,
8799 					 sna_output->backlight_active_level);
8800 	}
8801 
8802 	/* drain the event queue */
8803 	sna_mode_wakeup(sna);
8804 }
8805 
transformed_box(BoxRec * box,xf86CrtcPtr crtc)8806 static void transformed_box(BoxRec *box, xf86CrtcPtr crtc)
8807 {
8808 	box->x1 -= crtc->filter_width >> 1;
8809 	box->x2 += crtc->filter_width >> 1;
8810 	box->y1 -= crtc->filter_height >> 1;
8811 	box->y2 += crtc->filter_height >> 1;
8812 
8813 	pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc, box);
8814 
8815 	if (box->x1 < 0)
8816 		box->x1 = 0;
8817 	if (box->y1 < 0)
8818 		box->y1 = 0;
8819 	if (box->x2 > crtc->mode.HDisplay)
8820 		box->x2 = crtc->mode.HDisplay;
8821 	if (box->y2 > crtc->mode.VDisplay)
8822 		box->y2 = crtc->mode.VDisplay;
8823 }
8824 
crtc_source(xf86CrtcPtr crtc,int16_t * sx,int16_t * sy)8825 inline static DrawablePtr crtc_source(xf86CrtcPtr crtc, int16_t *sx, int16_t *sy)
8826 {
8827 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
8828 	if (sna_crtc->slave_pixmap) {
8829 		DBG(("%s: using slave pixmap=%ld, offset (%d, %d)\n",
8830 		     __FUNCTION__,
8831 		     sna_crtc->slave_pixmap->drawable.serialNumber,
8832 		 -crtc->x, -crtc->y));
8833 		*sx = -crtc->x;
8834 		*sy = -crtc->y;
8835 		return &sna_crtc->slave_pixmap->drawable;
8836 	} else {
8837 		DBG(("%s: using Screen pixmap=%ld\n",
8838 		     __FUNCTION__,
8839 		     to_sna(crtc->scrn)->front->drawable.serialNumber));
8840 		*sx = *sy = 0;
8841 		return &to_sna(crtc->scrn)->front->drawable;
8842 	}
8843 }
8844 
8845 static void
sna_crtc_redisplay__fallback(xf86CrtcPtr crtc,RegionPtr region,struct kgem_bo * bo)8846 sna_crtc_redisplay__fallback(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo)
8847 {
8848 	int16_t sx, sy;
8849 	struct sna *sna = to_sna(crtc->scrn);
8850 	ScreenPtr screen = xf86ScrnToScreen(crtc->scrn);
8851 	DrawablePtr draw = crtc_source(crtc, &sx, &sy);
8852 	PictFormatPtr format;
8853 	PictTransform T;
8854 	PicturePtr src, dst;
8855 	PixmapPtr pixmap;
8856 	int depth, error;
8857 	void *ptr;
8858 
8859 	DBG(("%s: compositing transformed damage boxes, target handle=%d\n", __FUNCTION__, bo->handle));
8860 
8861 	error = sna_render_format_for_depth(draw->depth);
8862 	depth = PIXMAN_FORMAT_DEPTH(error);
8863 	format = PictureMatchFormat(screen, depth, error);
8864 	if (format == NULL) {
8865 		DBG(("%s: can't find format for depth=%d [%08x]\n",
8866 		     __FUNCTION__, depth, error));
8867 		return;
8868 	}
8869 
8870 	DBG(("%s: dst format=%08x, depth=%d, bpp=%d, pitch=%d, size=%dx%d\n",
8871 	     __FUNCTION__, format->format, depth, draw->bitsPerPixel,
8872 	     bo->pitch, crtc->mode.HDisplay, crtc->mode.VDisplay));
8873 
8874 	if (sx | sy)
8875 		RegionTranslate(region, sx, sy);
8876 	error = !sna_drawable_move_region_to_cpu(draw, region, MOVE_READ);
8877 	if (sx | sy)
8878 		RegionTranslate(region, -sx, -sy);
8879 	if (error)
8880 		return;
8881 
8882 	ptr = kgem_bo_map__gtt(&sna->kgem, bo);
8883 	if (ptr == NULL)
8884 		return;
8885 
8886 	pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth);
8887 	if (pixmap == NullPixmap)
8888 		return;
8889 
8890 	if (!screen->ModifyPixmapHeader(pixmap,
8891 					crtc->mode.HDisplay, crtc->mode.VDisplay,
8892 					depth, draw->bitsPerPixel,
8893 					bo->pitch, ptr))
8894 		goto free_pixmap;
8895 
8896 	src = CreatePicture(None, draw, format,
8897 			    0, NULL, serverClient, &error);
8898 	if (!src)
8899 		goto free_pixmap;
8900 
8901 	pixman_transform_init_translate(&T, sx << 16, sy << 16);
8902 	pixman_transform_multiply(&T, &T, &crtc->crtc_to_framebuffer);
8903 	if (!sna_transform_is_integer_translation(&T, &sx, &sy)) {
8904 #define f2d(x) (((double)(x))/65536.)
8905 		DBG(("%s: transform=[[%f %f %f], [%f %f %f], [%f %f %f]] (raw [[%x %x %x], [%x %x %x], [%x %x %x]])\n",
8906 		     __FUNCTION__,
8907 		     f2d(T.matrix[0][0]),
8908 		     f2d(T.matrix[0][1]),
8909 		     f2d(T.matrix[0][2]),
8910 		     f2d(T.matrix[1][0]),
8911 		     f2d(T.matrix[1][1]),
8912 		     f2d(T.matrix[1][2]),
8913 		     f2d(T.matrix[2][0]),
8914 		     f2d(T.matrix[2][1]),
8915 		     f2d(T.matrix[2][2]),
8916 		     T.matrix[0][0],
8917 		     T.matrix[0][1],
8918 		     T.matrix[0][2],
8919 		     T.matrix[1][0],
8920 		     T.matrix[1][1],
8921 		     T.matrix[1][2],
8922 		     T.matrix[2][0],
8923 		     T.matrix[2][1],
8924 		     T.matrix[2][2]));
8925 #undef f2d
8926 
8927 		error = SetPictureTransform(src, &T);
8928 		if (error)
8929 			goto free_src;
8930 		sx = sy = 0;
8931 	}
8932 
8933 	if (crtc->filter && crtc->transform_in_use)
8934 		SetPicturePictFilter(src, crtc->filter,
8935 				     crtc->params, crtc->nparams);
8936 
8937 	dst = CreatePicture(None, &pixmap->drawable, format,
8938 			    0, NULL, serverClient, &error);
8939 	if (!dst)
8940 		goto free_src;
8941 
8942 	kgem_bo_sync__gtt(&sna->kgem, bo);
8943 
8944 	if (sigtrap_get() == 0) { /* paranoia */
8945 		const BoxRec *b = region_rects(region);
8946 		int n = region_num_rects(region);
8947 		do {
8948 			BoxRec box;
8949 
8950 			box = *b++;
8951 			transformed_box(&box, crtc);
8952 
8953 			DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n",
8954 			     __FUNCTION__,
8955 			     b[-1].x1, b[-1].y1, b[-1].x2-b[-1].x1, b[-1].y2-b[-1].y1,
8956 			     box.x1, box.y1, box.x2, box.y2));
8957 
8958 			fbComposite(PictOpSrc, src, NULL, dst,
8959 				    box.x1 + sx, box.y1 + sy,
8960 				    0, 0,
8961 				    box.x1, box.y1,
8962 				    box.x2 - box.x1, box.y2 - box.y1);
8963 		} while (--n);
8964 		sigtrap_put();
8965 	}
8966 
8967 	FreePicture(dst, None);
8968 free_src:
8969 	FreePicture(src, None);
8970 free_pixmap:
8971 	screen->DestroyPixmap(pixmap);
8972 }
8973 
8974 static void
sna_crtc_redisplay__composite(xf86CrtcPtr crtc,RegionPtr region,struct kgem_bo * bo)8975 sna_crtc_redisplay__composite(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo)
8976 {
8977 	int16_t sx, sy;
8978 	struct sna *sna = to_sna(crtc->scrn);
8979 	ScreenPtr screen = xf86ScrnToScreen(crtc->scrn);
8980 	DrawablePtr draw = crtc_source(crtc, &sx, &sy);
8981 	struct sna_composite_op tmp;
8982 	PictFormatPtr format;
8983 	PictTransform T;
8984 	PicturePtr src, dst;
8985 	PixmapPtr pixmap;
8986 	const BoxRec *b;
8987 	int n, depth, error;
8988 
8989 	DBG(("%s: compositing transformed damage boxes\n", __FUNCTION__));
8990 
8991 	error = sna_render_format_for_depth(draw->depth);
8992 	depth = PIXMAN_FORMAT_DEPTH(error);
8993 	format = PictureMatchFormat(screen, depth, error);
8994 	if (format == NULL) {
8995 		DBG(("%s: can't find format for depth=%d [%08x]\n",
8996 		     __FUNCTION__, depth, error));
8997 		return;
8998 	}
8999 
9000 	DBG(("%s: dst format=%08x, depth=%d, bpp=%d, pitch=%d, size=%dx%d\n",
9001 	     __FUNCTION__, format->format, depth, draw->bitsPerPixel,
9002 	     bo->pitch, crtc->mode.HDisplay, crtc->mode.VDisplay));
9003 
9004 	pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth);
9005 	if (pixmap == NullPixmap)
9006 		return;
9007 
9008 	if (!screen->ModifyPixmapHeader(pixmap,
9009 					crtc->mode.HDisplay, crtc->mode.VDisplay,
9010 					depth, draw->bitsPerPixel,
9011 					bo->pitch, NULL))
9012 		goto free_pixmap;
9013 
9014 	if (!sna_pixmap_attach_to_bo(pixmap, kgem_bo_reference(bo))) {
9015 		kgem_bo_destroy(&sna->kgem, bo);
9016 		goto free_pixmap;
9017 	}
9018 
9019 	src = CreatePicture(None, draw, format,
9020 			    0, NULL, serverClient, &error);
9021 	if (!src)
9022 		goto free_pixmap;
9023 
9024 	pixman_transform_init_translate(&T, sx << 16, sy << 16);
9025 	pixman_transform_multiply(&T, &T, &crtc->crtc_to_framebuffer);
9026 	if (!sna_transform_is_integer_translation(&T, &sx, &sy)) {
9027 		error = SetPictureTransform(src, &T);
9028 		if (error)
9029 			goto free_src;
9030 		sx = sy = 0;
9031 	}
9032 
9033 	if (crtc->filter && crtc->transform_in_use)
9034 		SetPicturePictFilter(src, crtc->filter,
9035 				     crtc->params, crtc->nparams);
9036 
9037 	dst = CreatePicture(None, &pixmap->drawable, format,
9038 			    0, NULL, serverClient, &error);
9039 	if (!dst)
9040 		goto free_src;
9041 
9042 	ValidatePicture(src);
9043 	ValidatePicture(dst);
9044 
9045 	/* Composite each box individually as if we are dealing with a rotation
9046 	 * on a large display, we may have to perform intermediate copies. We
9047 	 * can then minimise the overdraw by looking at individual boxes rather
9048 	 * than the bbox.
9049 	 */
9050 	n = region_num_rects(region);
9051 	b = region_rects(region);
9052 	do {
9053 		BoxRec box = *b;
9054 		transformed_box(&box, crtc);
9055 
9056 		DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n",
9057 		     __FUNCTION__,
9058 		     b->x1, b->y1, b->x2-b->x1, b->y2-b->y1,
9059 		     box.x1, box.y1, box.x2, box.y2));
9060 
9061 		if (!sna->render.composite(sna,
9062 					   PictOpSrc, src, NULL, dst,
9063 					   sx + box.x1, sy + box.y1,
9064 					   0, 0,
9065 					   box.x1, box.y1,
9066 					   box.x2 - box.x1, box.y2 - box.y1,
9067 					   0, memset(&tmp, 0, sizeof(tmp)))) {
9068 			DBG(("%s: unsupported operation!\n", __FUNCTION__));
9069 			sna_crtc_redisplay__fallback(crtc, region, bo);
9070 			break;
9071 		} else {
9072 			tmp.box(sna, &tmp, &box);
9073 			tmp.done(sna, &tmp);
9074 		}
9075 	} while (b++, --n);
9076 
9077 	FreePicture(dst, None);
9078 free_src:
9079 	FreePicture(src, None);
9080 free_pixmap:
9081 	screen->DestroyPixmap(pixmap);
9082 }
9083 
9084 static void
sna_crtc_redisplay(xf86CrtcPtr crtc,RegionPtr region,struct kgem_bo * bo)9085 sna_crtc_redisplay(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo)
9086 {
9087 	int16_t tx, ty, sx, sy;
9088 	struct sna *sna = to_sna(crtc->scrn);
9089 	DrawablePtr draw = crtc_source(crtc, &sx, &sy);
9090 	struct sna_pixmap *priv = sna_pixmap((PixmapPtr)draw);
9091 
9092 	DBG(("%s: crtc %d [pipe=%d], damage (%d, %d), (%d, %d) x %d\n",
9093 	     __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc),
9094 	     region->extents.x1, region->extents.y1,
9095 	     region->extents.x2, region->extents.y2,
9096 	     region_num_rects(region)));
9097 
9098 	if (wedged(sna))
9099 		goto fallback;
9100 
9101 	if (priv->clear) {
9102 		RegionRec whole;
9103 
9104 		DBG(("%s: clear damage boxes\n", __FUNCTION__));
9105 
9106 		if (sna_transform_is_integer_translation(&crtc->crtc_to_framebuffer,
9107 							 &tx, &ty)) {
9108 			RegionTranslate(region, -tx, -ty);
9109 		} else {
9110 			whole.extents = region->extents;
9111 			whole.data = NULL;
9112 			transformed_box(&whole.extents, crtc);
9113 			region = &whole;
9114 		}
9115 		if (sna_blt_fill_boxes(sna, GXcopy,
9116 				       bo, draw->bitsPerPixel,
9117 				       priv->clear_color,
9118 				       region_rects(region),
9119 				       region_num_rects(region)))
9120 			return;
9121 	}
9122 
9123 	if (crtc->filter == NULL &&
9124 	    priv->gpu_bo &&
9125 	    priv->cpu_damage == NULL &&
9126 	    sna_transform_is_integer_translation(&crtc->crtc_to_framebuffer,
9127 						 &tx, &ty)) {
9128 		DrawableRec tmp;
9129 
9130 		DBG(("%s: copy damage boxes\n", __FUNCTION__));
9131 
9132 		tmp.width = crtc->mode.HDisplay;
9133 		tmp.height = crtc->mode.VDisplay;
9134 		tmp.depth = sna->front->drawable.depth;
9135 		tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
9136 
9137 		if (sna->render.copy_boxes(sna, GXcopy,
9138 					   draw, priv->gpu_bo, sx, sy,
9139 					   &tmp, bo, -tx, -ty,
9140 					   region_rects(region), region_num_rects(region), 0))
9141 			return;
9142 	}
9143 
9144 	if (can_render(sna)) {
9145 		sna_crtc_redisplay__composite(crtc, region, bo);
9146 		return;
9147 	}
9148 
9149 fallback:
9150 	sna_crtc_redisplay__fallback(crtc, region, bo);
9151 }
9152 
shadow_flip_handler(struct drm_event_vblank * e,void * data)9153 static void shadow_flip_handler(struct drm_event_vblank *e,
9154 				void *data)
9155 {
9156 	struct sna *sna = data;
9157 
9158 	sna->timer_active |= 1 << FLUSH_TIMER;
9159 	sna->timer_expire[FLUSH_TIMER] =
9160 		e->tv_sec * 1000 + e->tv_usec / 1000 +
9161 		sna->vblank_interval / 2;
9162 }
9163 
sna_shadow_set_crtc(struct sna * sna,xf86CrtcPtr crtc,struct kgem_bo * bo)9164 void sna_shadow_set_crtc(struct sna *sna,
9165 			 xf86CrtcPtr crtc,
9166 			 struct kgem_bo *bo)
9167 {
9168 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
9169 	struct sna_pixmap *priv;
9170 
9171 	assert(sna_crtc);
9172 	DBG(("%s: setting shadow override for CRTC:%d to handle=%d\n",
9173 	     __FUNCTION__, __sna_crtc_id(sna_crtc), bo->handle));
9174 
9175 	assert(sna->flags & SNA_TEAR_FREE);
9176 	assert(!sna_crtc->transform);
9177 
9178 	if (sna_crtc->client_bo != bo) {
9179 		if (sna_crtc->client_bo) {
9180 			assert(sna_crtc->client_bo->refcnt >= sna_crtc->client_bo->active_scanout);
9181 			sna_crtc->client_bo->active_scanout--;
9182 			kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo);
9183 		}
9184 
9185 		sna_crtc->client_bo = kgem_bo_reference(bo);
9186 		sna_crtc->client_bo->active_scanout++;
9187 		assert(sna_crtc->client_bo->refcnt >= sna_crtc->client_bo->active_scanout);
9188 		sna_crtc_damage(crtc);
9189 	}
9190 
9191 	list_move(&sna_crtc->shadow_link, &sna->mode.shadow_crtc);
9192 	sna->mode.shadow_dirty = true;
9193 
9194 	priv = sna_pixmap(sna->front);
9195 	assert(priv->gpu_bo);
9196 	priv->move_to_gpu = wait_for_shadow;
9197 	priv->move_to_gpu_data = sna;
9198 }
9199 
sna_shadow_steal_crtcs(struct sna * sna,struct list * list)9200 void sna_shadow_steal_crtcs(struct sna *sna, struct list *list)
9201 {
9202 	list_init(list);
9203 	while (!list_is_empty(&sna->mode.shadow_crtc)) {
9204 		RegionRec sub, *damage;
9205 		struct sna_crtc *crtc =
9206 			list_first_entry(&sna->mode.shadow_crtc,
9207 					 struct sna_crtc,
9208 					 shadow_link);
9209 
9210 		damage = DamageRegion(sna->mode.shadow_damage);
9211 		sub.extents = crtc->base->bounds;
9212 		sub.data = NULL;
9213 		RegionSubtract(damage, damage, &sub);
9214 
9215 		list_move(&crtc->shadow_link, list);
9216 	}
9217 }
9218 
sna_shadow_unsteal_crtcs(struct sna * sna,struct list * list)9219 void sna_shadow_unsteal_crtcs(struct sna *sna, struct list *list)
9220 {
9221 	while (!list_is_empty(list)) {
9222 		struct sna_crtc *crtc =
9223 			list_first_entry(list,
9224 					 struct sna_crtc,
9225 					 shadow_link);
9226 		assert(crtc->client_bo);
9227 		sna_shadow_set_crtc(sna, crtc->base, crtc->client_bo);
9228 	}
9229 }
9230 
sna_shadow_unset_crtc(struct sna * sna,xf86CrtcPtr crtc)9231 void sna_shadow_unset_crtc(struct sna *sna,
9232 			   xf86CrtcPtr crtc)
9233 {
9234 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
9235 
9236 	DBG(("%s: clearin shadow override for CRTC:%d\n",
9237 	     __FUNCTION__, __sna_crtc_id(sna_crtc)));
9238 
9239 	if (sna_crtc->client_bo == NULL)
9240 		return;
9241 
9242 	assert(sna_crtc->client_bo->refcnt >= sna_crtc->client_bo->active_scanout);
9243 	sna_crtc->client_bo->active_scanout--;
9244 	kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo);
9245 	sna_crtc->client_bo = NULL;
9246 	list_del(&sna_crtc->shadow_link);
9247 	sna->mode.shadow_dirty = true;
9248 
9249 	sna_crtc_damage(crtc);
9250 }
9251 
move_crtc_to_gpu(struct sna * sna)9252 static bool move_crtc_to_gpu(struct sna *sna)
9253 {
9254 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
9255 	int i;
9256 
9257 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
9258 		struct sna_crtc *crtc = to_sna_crtc(config->crtc[i]);
9259 		unsigned hint;
9260 
9261 		assert(crtc);
9262 
9263 		if (crtc->bo == NULL)
9264 			continue;
9265 
9266 		if (crtc->slave_pixmap)
9267 			continue;
9268 
9269 		if (crtc->client_bo)
9270 			continue;
9271 
9272 		if (crtc->shadow_bo)
9273 			continue;
9274 
9275 		hint = MOVE_READ | MOVE_ASYNC_HINT | __MOVE_SCANOUT;
9276 		if (sna->flags & SNA_TEAR_FREE)
9277 			hint |= __MOVE_FORCE;
9278 
9279 		DBG(("%s: CRTC %d [pipe=%d] requires frontbuffer\n",
9280 		     __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc)));
9281 		return sna_pixmap_move_to_gpu(sna->front, hint);
9282 	}
9283 
9284 	return true;
9285 }
9286 
sna_mode_redisplay(struct sna * sna)9287 void sna_mode_redisplay(struct sna *sna)
9288 {
9289 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
9290 	RegionPtr region;
9291 	int i;
9292 
9293 	if (sna->mode.hidden) {
9294 		DBG(("%s: hidden outputs, skipping\n", __FUNCTION__));
9295 		return;
9296 	}
9297 
9298 	if (!sna->mode.shadow_enabled)
9299 		return;
9300 
9301 	assert(sna->mode.shadow_damage);
9302 
9303 	DBG(("%s: posting shadow damage? %d (flips pending? %d, mode reconfiguration pending? %d)\n",
9304 	     __FUNCTION__,
9305 	     !RegionNil(DamageRegion(sna->mode.shadow_damage)),
9306 	     sna->mode.flip_active,
9307 	     sna->mode.dirty));
9308 	assert((sna->flags & SNA_IS_HOSTED) == 0);
9309 	assert(sna->mode.shadow_active);
9310 
9311 	if (sna->mode.dirty)
9312 		return;
9313 
9314 	if (sna->mode.flip_active) {
9315 		DBG(("%s: %d outstanding flips\n",
9316 		     __FUNCTION__, sna->mode.flip_active));
9317 		return;
9318 	}
9319 
9320 	region = DamageRegion(sna->mode.shadow_damage);
9321 	if (RegionNil(region))
9322 		return;
9323 
9324 	DBG(("%s: damage: %dx(%d, %d), (%d, %d)\n",
9325 	     __FUNCTION__, region_num_rects(region),
9326 	     region->extents.x1, region->extents.y1,
9327 	     region->extents.x2, region->extents.y2));
9328 
9329 	if (!move_crtc_to_gpu(sna)) {
9330 		DBG(("%s: forcing scanout update using the CPU\n", __FUNCTION__));
9331 		if (!sna_pixmap_move_to_cpu(sna->front, MOVE_READ))
9332 			return;
9333 
9334 		for (i = 0; i < sna->mode.num_real_crtc; i++) {
9335 			xf86CrtcPtr crtc = config->crtc[i];
9336 			struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
9337 			RegionRec damage;
9338 
9339 			assert(sna_crtc != NULL);
9340 			if (!sna_crtc->shadow)
9341 				continue;
9342 
9343 			assert(crtc->enabled);
9344 			assert(sna_crtc->transform || sna->flags & SNA_TEAR_FREE);
9345 
9346 			damage.extents = crtc->bounds;
9347 			damage.data = NULL;
9348 			RegionIntersect(&damage, &damage, region);
9349 			if (!box_empty(&damage.extents)) {
9350 				DBG(("%s: fallback intersects pipe=%d [(%d, %d), (%d, %d)]\n",
9351 				     __FUNCTION__, __sna_crtc_pipe(sna_crtc),
9352 				     damage.extents.x1, damage.extents.y1,
9353 				     damage.extents.x2, damage.extents.y2));
9354 
9355 				sna_crtc_redisplay__fallback(crtc,
9356 							     &damage,
9357 							     sna_crtc->bo);
9358 			}
9359 			RegionUninit(&damage);
9360 
9361 			if (sna_crtc->slave_damage)
9362 				DamageEmpty(sna_crtc->slave_damage);
9363 		}
9364 
9365 		RegionEmpty(region);
9366 		return;
9367 	}
9368 
9369 	{
9370 		struct sna_pixmap *priv;
9371 
9372 		priv = sna_pixmap(sna->front);
9373 		assert(priv != NULL);
9374 
9375 		if (priv->move_to_gpu) {
9376 			if (priv->move_to_gpu == wait_for_shadow &&
9377 			    !sna->mode.shadow_dirty) {
9378 				/* No damage written to new scanout
9379 				 * (backbuffer), ignore redisplay request
9380 				 * and continue with the current intact
9381 				 * scanout (frontbuffer).
9382 				 */
9383 				DBG(("%s: shadow idle, skipping update\n", __FUNCTION__));
9384 				RegionEmpty(region);
9385 				return;
9386 			}
9387 
9388 			(void)priv->move_to_gpu(sna, priv, 0);
9389 		}
9390 
9391 		assert(priv->move_to_gpu == NULL);
9392 	}
9393 
9394 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
9395 		xf86CrtcPtr crtc = config->crtc[i];
9396 		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
9397 		RegionRec damage;
9398 		int sigio;
9399 
9400 		assert(sna_crtc != NULL);
9401 		DBG(("%s: crtc[%d] transformed? %d\n",
9402 		     __FUNCTION__, i, sna_crtc->transform));
9403 
9404 		if (!sna_crtc->transform)
9405 			continue;
9406 
9407 		assert(crtc->enabled);
9408 		assert(sna_crtc->bo);
9409 
9410 		damage.extents = crtc->bounds;
9411 		damage.data = NULL;
9412 
9413 		RegionIntersect(&damage, &damage, region);
9414 		DBG(("%s: crtc[%d] damage? %d[%d]: %dx[(%d, %d), (%d, %d)]\n",
9415 		     __FUNCTION__, i,
9416 		     !box_empty(&damage.extents), RegionNotEmpty(&damage),
9417 		     region_num_rects(&damage),
9418 		     damage.extents.x1, damage.extents.y1,
9419 		     damage.extents.x2, damage.extents.y2));
9420 		sigio = sigio_block();
9421 		if (!box_empty(&damage.extents)) {
9422 			if (sna->flags & SNA_TEAR_FREE) {
9423 				RegionRec new_damage;
9424 				struct drm_mode_crtc_page_flip arg;
9425 				struct kgem_bo *bo;
9426 
9427 				RegionNull(&new_damage);
9428 				RegionCopy(&new_damage, &damage);
9429 
9430 				bo = sna_crtc->cache_bo;
9431 				if (bo == NULL) {
9432 					damage.extents = crtc->bounds;
9433 					damage.data = NULL;
9434 					bo = kgem_create_2d(&sna->kgem,
9435 							    crtc->mode.HDisplay,
9436 							    crtc->mode.VDisplay,
9437 							    crtc->scrn->bitsPerPixel,
9438 							    sna_crtc->bo->tiling,
9439 							    CREATE_SCANOUT);
9440 					if (bo == NULL)
9441 						continue;
9442 				} else
9443 					RegionUnion(&damage, &damage, &sna_crtc->crtc_damage);
9444 				sna_crtc->crtc_damage = new_damage;
9445 
9446 				sna_crtc_redisplay(crtc, &damage, bo);
9447 				kgem_bo_submit(&sna->kgem, bo);
9448 				__kgem_bo_clear_dirty(bo);
9449 
9450 				assert_crtc_fb(sna, sna_crtc);
9451 				arg.crtc_id = __sna_crtc_id(sna_crtc);
9452 				arg.fb_id = get_fb(sna, bo,
9453 						   crtc->mode.HDisplay,
9454 						   crtc->mode.VDisplay);
9455 				if (arg.fb_id == 0)
9456 					goto disable1;
9457 
9458 				arg.user_data = (uintptr_t)sna_crtc;
9459 				arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
9460 				arg.reserved = 0;
9461 
9462 				if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
9463 					if (sna_crtc_flip(sna, sna_crtc, bo, 0, 0)) {
9464 						DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n",
9465 						     __FUNCTION__, sna_crtc->bo->handle, sna_crtc->bo->active_scanout - 1,
9466 						     bo->handle, bo->active_scanout));
9467 						assert(sna_crtc->bo->active_scanout);
9468 						assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout);
9469 						sna_crtc->bo->active_scanout--;
9470 						kgem_bo_destroy(&sna->kgem, sna_crtc->bo);
9471 
9472 						sna_crtc->bo = kgem_bo_reference(bo);
9473 						sna_crtc->bo->active_scanout++;
9474 					} else {
9475 						BoxRec box;
9476 						DrawableRec tmp;
9477 
9478 						DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n",
9479 						     __FUNCTION__, arg.fb_id, i, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), errno));
9480 						xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
9481 							   "Page flipping failed, disabling TearFree\n");
9482 						sna->flags &= ~SNA_TEAR_FREE;
9483 
9484 disable1:
9485 						box.x1 = 0;
9486 						box.y1 = 0;
9487 						tmp.width = box.x2 = crtc->mode.HDisplay;
9488 						tmp.height = box.y2 = crtc->mode.VDisplay;
9489 						tmp.depth = sna->front->drawable.depth;
9490 						tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
9491 
9492 						if (!sna->render.copy_boxes(sna, GXcopy,
9493 									    &sna->front->drawable, bo, 0, 0,
9494 									    &tmp, sna_crtc->bo, 0, 0,
9495 									    &box, 1, COPY_LAST)) {
9496 							xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
9497 								   "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n",
9498 								   __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc));
9499 							sna_crtc_disable(crtc, false);
9500 						}
9501 					}
9502 
9503 					kgem_bo_destroy(&sna->kgem, bo);
9504 					sna_crtc->cache_bo = NULL;
9505 					continue;
9506 				}
9507 				sna->mode.flip_active++;
9508 
9509 				assert(sna_crtc->flip_bo == NULL);
9510 				sna_crtc->flip_handler = shadow_flip_handler;
9511 				sna_crtc->flip_data = sna;
9512 				sna_crtc->flip_bo = bo;
9513 				sna_crtc->flip_bo->active_scanout++;
9514 				sna_crtc->flip_serial = sna_crtc->mode_serial;
9515 				sna_crtc->flip_pending = true;
9516 
9517 				if (sna_crtc->bo != sna->mode.shadow) {
9518 					assert_scanout(&sna->kgem, sna_crtc->bo,
9519 						       crtc->mode.HDisplay, crtc->mode.VDisplay);
9520 					sna_crtc->cache_bo = kgem_bo_reference(sna_crtc->bo);
9521 				}
9522 				DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n",
9523 				     __FUNCTION__, __sna_crtc_id(sna_crtc), sna_crtc->flip_bo->handle, sna_crtc->flip_bo->active_scanout, sna_crtc->flip_serial));
9524 			} else {
9525 				sna_crtc_redisplay(crtc, &damage, sna_crtc->bo);
9526 				kgem_scanout_flush(&sna->kgem, sna_crtc->bo);
9527 			}
9528 		}
9529 		RegionUninit(&damage);
9530 		sigio_unblock(sigio);
9531 
9532 		if (sna_crtc->slave_damage)
9533 			DamageEmpty(sna_crtc->slave_damage);
9534 	}
9535 
9536 	if (sna->mode.shadow) {
9537 		struct kgem_bo *new = __sna_pixmap_get_bo(sna->front);
9538 		struct kgem_bo *old = sna->mode.shadow;
9539 		struct drm_mode_crtc_page_flip arg;
9540 		uint32_t fb = 0;
9541 		int sigio;
9542 
9543 		DBG(("%s: flipping TearFree outputs, current scanout handle=%d [active?=%d], new handle=%d [active=%d]\n",
9544 		     __FUNCTION__, old->handle, old->active_scanout, new->handle, new->active_scanout));
9545 
9546 		assert(new != old);
9547 		assert(new->refcnt);
9548 
9549 		arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
9550 		arg.reserved = 0;
9551 
9552 		kgem_bo_submit(&sna->kgem, new);
9553 		__kgem_bo_clear_dirty(new);
9554 
9555 		sigio = sigio_block();
9556 		for (i = 0; i < sna->mode.num_real_crtc; i++) {
9557 			struct sna_crtc *crtc = config->crtc[i]->driver_private;
9558 			struct kgem_bo *flip_bo;
9559 			int x, y;
9560 
9561 			assert(crtc != NULL);
9562 			DBG(("%s: crtc %d [%d, pipe=%d] active? %d, transformed? %d\n",
9563 			     __FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->bo ? crtc->bo->handle : 0, crtc->transform));
9564 			if (crtc->bo == NULL || crtc->transform)
9565 				continue;
9566 
9567 			assert(config->crtc[i]->enabled);
9568 			assert(crtc->flip_bo == NULL);
9569 			assert_crtc_fb(sna, crtc);
9570 
9571 			arg.crtc_id = __sna_crtc_id(crtc);
9572 			arg.user_data = (uintptr_t)crtc;
9573 
9574 			if (crtc->client_bo) {
9575 				DBG(("%s: apply shadow override bo for CRTC:%d on pipe=%d, handle=%d\n",
9576 				     __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->client_bo->handle));
9577 				arg.fb_id = get_fb(sna, crtc->client_bo,
9578 						   crtc->base->mode.HDisplay,
9579 						   crtc->base->mode.VDisplay);
9580 				assert(arg.fb_id != fb);
9581 				flip_bo = crtc->client_bo;
9582 				x = y = 0;
9583 			} else {
9584 				if (fb == 0)
9585 					fb = get_fb(sna, new, sna->scrn->virtualX, sna->scrn->virtualY);
9586 				if (fb == 0) {
9587 fixup_shadow:
9588 					if (sna_pixmap_move_to_gpu(sna->front, MOVE_READ | MOVE_ASYNC_HINT)) {
9589 						BoxRec box;
9590 
9591 						box.x1 = 0;
9592 						box.y1 = 0;
9593 						box.x2 = sna->scrn->virtualX;
9594 						box.y2 = sna->scrn->virtualY;
9595 						if (sna->render.copy_boxes(sna, GXcopy,
9596 									   &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0,
9597 									   &sna->front->drawable, old, 0, 0,
9598 									   &box, 1, COPY_LAST)) {
9599 							kgem_submit(&sna->kgem);
9600 							RegionEmpty(region);
9601 						}
9602 					}
9603 
9604 					sigio_unblock(sigio);
9605 					return;
9606 				}
9607 
9608 				arg.fb_id = fb;
9609 				flip_bo = new;
9610 				x = crtc->base->x;
9611 				y = crtc->base->y;
9612 			}
9613 
9614 			if (crtc->bo == flip_bo) {
9615 				assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
9616 				DBG(("%s: flip handle=%d is already on the CRTC\n",
9617 				     __FUNCTION__, flip_bo->handle));
9618 				continue;
9619 			}
9620 
9621 			if (flip_bo->pitch != crtc->bo->pitch || (y << 16 | x)  != crtc->offset) {
9622 				DBG(("%s: changing pitch (new %d =?= old %d) or offset (new %x =?= old %x)\n",
9623 				     __FUNCTION__,
9624 				     flip_bo->pitch, crtc->bo->pitch,
9625 				     y << 16 | x, crtc->offset));
9626 fixup_flip:
9627 				if (sna_crtc_flip(sna, crtc, flip_bo, x, y)) {
9628 					DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n",
9629 					     __FUNCTION__, crtc->bo->handle, crtc->bo->active_scanout-1,
9630 					     flip_bo->handle, flip_bo->active_scanout));
9631 					assert(flip_bo != crtc->bo);
9632 					assert(crtc->bo->active_scanout);
9633 					assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
9634 					crtc->bo->active_scanout--;
9635 					kgem_bo_destroy(&sna->kgem, crtc->bo);
9636 
9637 					if (crtc->shadow_bo) {
9638 						kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
9639 						crtc->shadow_bo = NULL;
9640 					}
9641 
9642 					crtc->bo = kgem_bo_reference(flip_bo);
9643 					crtc->bo->active_scanout++;
9644 				} else {
9645 					if (sna->flags & SNA_TEAR_FREE) {
9646 						xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
9647 								"Failed to prepare CRTC for page flipping, disabling TearFree\n");
9648 						sna->flags &= ~SNA_TEAR_FREE;
9649 					}
9650 
9651 					if (sna->mode.flip_active == 0) {
9652 						DBG(("%s: abandoning flip attempt\n", __FUNCTION__));
9653 						goto fixup_shadow;
9654 					}
9655 
9656 					xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
9657 						   "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n",
9658 						   __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc));
9659 					sna_crtc_disable(crtc->base, false);
9660 				}
9661 				continue;
9662 			}
9663 
9664 			if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
9665 				ERR(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n",
9666 				     __FUNCTION__, arg.fb_id, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), errno));
9667 				goto fixup_flip;
9668 			}
9669 			sna->mode.flip_active++;
9670 
9671 			assert(crtc->flip_bo == NULL);
9672 			crtc->flip_handler = shadow_flip_handler;
9673 			crtc->flip_data = sna;
9674 			crtc->flip_bo = kgem_bo_reference(flip_bo);
9675 			crtc->flip_bo->active_scanout++;
9676 			crtc->flip_serial = crtc->mode_serial;
9677 			crtc->flip_pending = true;
9678 
9679 			DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n",
9680 			     __FUNCTION__, __sna_crtc_id(crtc), crtc->flip_bo->handle, crtc->flip_bo->active_scanout, crtc->flip_serial));
9681 
9682 			{
9683 				struct drm_i915_gem_busy busy = { .handle = flip_bo->handle, };
9684 				if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_BUSY, &busy) == 0) {
9685 					if (busy.busy) {
9686 						int mode = KGEM_RENDER;
9687 						if (busy.busy & (0xfffe << 16))
9688 							mode = KGEM_BLT;
9689 						DBG(("%s: marking flip bo as busy [%x -> mode=%d]\n", __FUNCTION__, busy.busy, mode));
9690 						kgem_bo_mark_busy(&sna->kgem, flip_bo, mode);
9691 					} else
9692 						__kgem_bo_clear_busy(flip_bo);
9693 				}
9694 			}
9695 		}
9696 		sigio_unblock(sigio);
9697 
9698 		DBG(("%s: flipped %d outputs, shadow active? %d\n",
9699 		     __FUNCTION__,
9700 		     sna->mode.flip_active,
9701 		     sna->mode.shadow ? sna->mode.shadow->handle : 0));
9702 
9703 		if (sna->mode.flip_active) {
9704 			assert(old == sna->mode.shadow);
9705 			assert(old->refcnt >= 1);
9706 			set_shadow(sna, region);
9707 		}
9708 	} else
9709 		kgem_submit(&sna->kgem);
9710 
9711 	RegionEmpty(region);
9712 }
9713 
sna_mode_wakeup(struct sna * sna)9714 int sna_mode_wakeup(struct sna *sna)
9715 {
9716 	bool defer_vblanks = sna->mode.flip_active && sna->mode.shadow_enabled;
9717 	char buffer[1024];
9718 	int len, i;
9719 	int ret = 0;
9720 
9721 again:
9722 	/* In order to workaround a kernel bug in not honouring O_NONBLOCK,
9723 	 * check that the fd is readable before attempting to read the next
9724 	 * event from drm.
9725 	 */
9726 	if (!event_pending(sna->kgem.fd))
9727 		goto done;
9728 
9729 	/* The DRM read semantics guarantees that we always get only
9730 	 * complete events.
9731 	 */
9732 	len = read(sna->kgem.fd, buffer, sizeof (buffer));
9733 	if (len < (int)sizeof(struct drm_event))
9734 		goto done;
9735 
9736 	/* Note that we cannot rely on the passed in struct sna matching
9737 	 * the struct sna used for the vblank event (in case it was submitted
9738 	 * by a different ZaphodHead). When processing the event, we must
9739 	 * ensure that we only use the pointer passed along with the event.
9740 	 */
9741 
9742 	DBG(("%s: len=%d\n", __FUNCTION__, len));
9743 
9744 	i = 0;
9745 	while (i < len) {
9746 		struct drm_event *e = (struct drm_event *)&buffer[i];
9747 		switch (e->type) {
9748 		case DRM_EVENT_VBLANK:
9749 			if (defer_vblanks)
9750 				defer_event(sna, e);
9751 			else if (((uintptr_t)((struct drm_event_vblank *)e)->user_data) & 2)
9752 				sna_present_vblank_handler((struct drm_event_vblank *)e);
9753 			else
9754 				sna_dri2_vblank_handler((struct drm_event_vblank *)e);
9755 			break;
9756 		case DRM_EVENT_FLIP_COMPLETE:
9757 			{
9758 				struct drm_event_vblank *vbl = (struct drm_event_vblank *)e;
9759 				struct sna_crtc *crtc = (void *)(uintptr_t)vbl->user_data;
9760 				uint64_t msc;
9761 
9762 				/* Beware Zaphod! */
9763 				sna = to_sna(crtc->base->scrn);
9764 
9765 				if (msc64(crtc, vbl->sequence, &msc)) {
9766 					DBG(("%s: recording last swap on pipe=%d, frame %d [%08llx], time %d.%06d\n",
9767 					     __FUNCTION__, __sna_crtc_pipe(crtc), vbl->sequence, (long long)msc, vbl->tv_sec, vbl->tv_usec));
9768 					crtc->swap.tv_sec = vbl->tv_sec;
9769 					crtc->swap.tv_usec = vbl->tv_usec;
9770 					crtc->swap.msc = msc;
9771 				}
9772 				assert(crtc->flip_pending);
9773 				crtc->flip_pending = false;
9774 
9775 				assert(crtc->flip_bo);
9776 				assert(crtc->flip_bo->active_scanout);
9777 				assert(crtc->flip_bo->refcnt >= crtc->flip_bo->active_scanout);
9778 
9779 				if (crtc->flip_serial == crtc->mode_serial) {
9780 					DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n",
9781 					     __FUNCTION__, crtc->bo->handle, crtc->bo->active_scanout - 1,
9782 					     crtc->flip_bo->handle, crtc->flip_bo->active_scanout));
9783 					assert(crtc->bo->active_scanout);
9784 					assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
9785 
9786 					crtc->bo->active_scanout--;
9787 					kgem_bo_destroy(&sna->kgem, crtc->bo);
9788 
9789 					if (crtc->shadow_bo) {
9790 						kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
9791 						crtc->shadow_bo = NULL;
9792 					}
9793 
9794 					crtc->bo = crtc->flip_bo;
9795 					crtc->flip_bo = NULL;
9796 
9797 					assert_crtc_fb(sna, crtc);
9798 				} else {
9799 					crtc->flip_bo->active_scanout--;
9800 					kgem_bo_destroy(&sna->kgem, crtc->flip_bo);
9801 					crtc->flip_bo = NULL;
9802 				}
9803 
9804 				DBG(("%s: flip complete, pending? %d\n", __FUNCTION__, sna->mode.flip_active));
9805 				assert(sna->mode.flip_active);
9806 				if (--sna->mode.flip_active == 0) {
9807 					assert(crtc->flip_handler);
9808 					crtc->flip_handler(vbl, crtc->flip_data);
9809 				}
9810 			}
9811 			break;
9812 		default:
9813 			break;
9814 		}
9815 		i += e->length;
9816 		ret++;
9817 	}
9818 
9819 	goto again;
9820 
9821 done:
9822 	flush_events(sna);
9823 	return ret;
9824 }
9825