sna_display.c revision 428d7b3d
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
43#include "sna.h"
44#include "sna_reg.h"
45#include "fb/fbpict.h"
46#include "intel_options.h"
47#include "backlight.h"
48
49#include <xf86Crtc.h>
50#include <xf86RandR12.h>
51#include <cursorstr.h>
52
53#if XF86_CRTC_VERSION >= 3
54#define HAS_GAMMA 1
55#else
56#define HAS_GAMMA 0
57#endif
58
59#include <X11/Xatom.h>
60#if defined(HAVE_X11_EXTENSIONS_DPMSCONST_H)
61#include <X11/extensions/dpmsconst.h>
62#else
63#define DPMSModeOn 0
64#define DPMSModeOff 3
65#endif
66#include <xf86DDC.h> /* for xf86InterpretEDID */
67
68#include <xf86drm.h>
69
70#ifdef HAVE_VALGRIND
71#include <valgrind.h>
72#include <memcheck.h>
73#endif
74
75/* Minor discrepancy between 32-bit/64-bit ABI in old kernels */
76union compat_mode_get_connector{
77	struct drm_mode_get_connector conn;
78	uint32_t pad[20];
79};
80
81#define KNOWN_MODE_FLAGS ((1<<14)-1)
82
83#ifndef MONITOR_EDID_COMPLETE_RAWDATA
84#define MONITOR_EDID_COMPLETE_RAWDATA 1
85#endif
86
87#ifndef DEFAULT_DPI
88#define DEFAULT_DPI 96
89#endif
90
91#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
92
93#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
94#define DRM_PLANE_TYPE_OVERLAY 0
95#define DRM_PLANE_TYPE_PRIMARY 1
96#define DRM_PLANE_TYPE_CURSOR  2
97
98#define LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xb9, struct local_mode_obj_get_properties)
99struct local_mode_obj_get_properties {
100	uint64_t props_ptr;
101	uint64_t prop_values_ptr;
102	uint32_t count_props;
103	uint32_t obj_id;
104	uint32_t obj_type;
105	uint32_t pad;
106};
107#define LOCAL_MODE_OBJECT_PLANE 0xeeeeeeee
108
109#if 0
110#define __DBG DBG
111#else
112#define __DBG(x)
113#endif
114
115extern XF86ConfigPtr xf86configptr;
116
117struct sna_crtc {
118	xf86CrtcPtr base;
119	struct drm_mode_modeinfo kmode;
120	int dpms_mode;
121	PixmapPtr slave_pixmap;
122	DamagePtr slave_damage;
123	struct kgem_bo *bo, *shadow_bo, *client_bo;
124	struct sna_cursor *cursor;
125	unsigned int last_cursor_size;
126	uint32_t offset;
127	bool shadow;
128	bool fallback_shadow;
129	bool transform;
130	bool flip_pending;
131	uint8_t id;
132	uint8_t pipe;
133
134	RegionRec client_damage; /* XXX overlap with shadow damage? */
135
136	uint16_t shadow_bo_width, shadow_bo_height;
137
138	uint32_t rotation;
139	struct plane {
140		uint32_t id;
141		struct {
142			uint32_t prop;
143			uint32_t supported;
144			uint32_t current;
145		} rotation;
146	} primary, sprite;
147
148	uint32_t mode_serial, flip_serial;
149
150	uint32_t last_seq, wrap_seq;
151	struct ust_msc swap;
152
153	sna_flip_handler_t flip_handler;
154	struct kgem_bo *flip_bo;
155	void *flip_data;
156
157	struct list shadow_link;
158};
159
160struct sna_property {
161	drmModePropertyPtr kprop;
162	int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */
163	Atom *atoms;
164};
165
166struct sna_output {
167	xf86OutputPtr base;
168	unsigned id;
169	unsigned serial;
170
171	unsigned possible_encoders;
172	unsigned attached_encoders;
173
174	unsigned int is_panel : 1;
175	unsigned int add_default_modes : 1;
176
177	uint32_t edid_idx;
178	uint32_t edid_blob_id;
179	uint32_t edid_len;
180	void *edid_raw;
181
182	bool has_panel_limits;
183	int panel_hdisplay;
184	int panel_vdisplay;
185
186	uint32_t dpms_id;
187	int dpms_mode;
188	struct backlight backlight;
189	int backlight_active_level;
190
191	int num_modes;
192	struct drm_mode_modeinfo *modes;
193
194	int num_props;
195	uint32_t *prop_ids;
196	uint64_t *prop_values;
197	struct sna_property *props;
198};
199
200enum { /* XXX copied from hw/xfree86/modes/xf86Crtc.c */
201	OPTION_PREFERRED_MODE,
202#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,1,0)
203	OPTION_ZOOM_MODES,
204#endif
205	OPTION_POSITION,
206	OPTION_BELOW,
207	OPTION_RIGHT_OF,
208	OPTION_ABOVE,
209	OPTION_LEFT_OF,
210	OPTION_ENABLE,
211	OPTION_DISABLE,
212	OPTION_MIN_CLOCK,
213	OPTION_MAX_CLOCK,
214	OPTION_IGNORE,
215	OPTION_ROTATE,
216	OPTION_PANNING,
217	OPTION_PRIMARY,
218	OPTION_DEFAULT_MODES,
219};
220
221static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc);
222
223static bool is_zaphod(ScrnInfoPtr scrn)
224{
225	return xf86IsEntityShared(scrn->entityList[0]);
226}
227
228inline static unsigned count_to_mask(int x)
229{
230	return (1 << x) - 1;
231}
232
233static inline struct sna_output *to_sna_output(xf86OutputPtr output)
234{
235	return output->driver_private;
236}
237
238static inline int to_connector_id(xf86OutputPtr output)
239{
240	assert(to_sna_output(output));
241	assert(to_sna_output(output)->id);
242	return to_sna_output(output)->id;
243}
244
245static inline struct sna_crtc *to_sna_crtc(xf86CrtcPtr crtc)
246{
247	return crtc->driver_private;
248}
249
250static inline bool event_pending(int fd)
251{
252	struct pollfd pfd;
253	pfd.fd = fd;
254	pfd.events = POLLIN;
255	return poll(&pfd, 1, 0) == 1;
256}
257
258static bool sna_mode_wait_for_event(struct sna *sna)
259{
260	struct pollfd pfd;
261	pfd.fd = sna->kgem.fd;
262	pfd.events = POLLIN;
263	return poll(&pfd, 1, -1) == 1;
264}
265
266static inline uint32_t fb_id(struct kgem_bo *bo)
267{
268	return bo->delta;
269}
270
271uint32_t sna_crtc_id(xf86CrtcPtr crtc)
272{
273	if (to_sna_crtc(crtc) == NULL)
274		return 0;
275	return to_sna_crtc(crtc)->id;
276}
277
278int sna_crtc_to_pipe(xf86CrtcPtr crtc)
279{
280	assert(to_sna_crtc(crtc));
281	return to_sna_crtc(crtc)->pipe;
282}
283
284uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc)
285{
286	assert(to_sna_crtc(crtc));
287	return to_sna_crtc(crtc)->sprite.id;
288}
289
290bool sna_crtc_is_on(xf86CrtcPtr crtc)
291{
292	assert(to_sna_crtc(crtc));
293	return to_sna_crtc(crtc)->bo != NULL;
294}
295
296bool sna_crtc_is_transformed(xf86CrtcPtr crtc)
297{
298	assert(to_sna_crtc(crtc));
299	return to_sna_crtc(crtc)->transform;
300}
301
302static inline uint64_t msc64(struct sna_crtc *sna_crtc, uint32_t seq)
303{
304	if (seq < sna_crtc->last_seq) {
305		if (sna_crtc->last_seq - seq > 0x40000000) {
306			sna_crtc->wrap_seq++;
307			DBG(("%s: pipe=%d wrapped; was %u, now %u, wraps=%u\n",
308			     __FUNCTION__, sna_crtc->pipe,
309			     sna_crtc->last_seq, seq, sna_crtc->wrap_seq));
310		} else  {
311			ERR(("%s: pipe=%d msc went backwards; was %u, now %u\n",
312			     __FUNCTION__, sna_crtc->pipe, sna_crtc->last_seq, seq));
313			seq = sna_crtc->last_seq;
314		}
315	}
316	sna_crtc->last_seq = seq;
317	return (uint64_t)sna_crtc->wrap_seq << 32 | seq;
318}
319
320uint64_t sna_crtc_record_swap(xf86CrtcPtr crtc,
321			      int tv_sec, int tv_usec, unsigned seq)
322{
323	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
324	assert(sna_crtc);
325	DBG(("%s: recording last swap on pipe=%d, frame %d, time %d.%06d\n",
326	     __FUNCTION__, sna_crtc->pipe, seq, tv_sec, tv_usec));
327	sna_crtc->swap.tv_sec = tv_sec;
328	sna_crtc->swap.tv_usec = tv_usec;
329	return sna_crtc->swap.msc = msc64(sna_crtc, seq);
330}
331
332const struct ust_msc *sna_crtc_last_swap(xf86CrtcPtr crtc)
333{
334	static struct ust_msc zero;
335
336	if (crtc == NULL) {
337		return &zero;
338	} else {
339		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
340		assert(sna_crtc);
341		return &sna_crtc->swap;
342	}
343}
344
345xf86CrtcPtr sna_mode_first_crtc(struct sna *sna)
346{
347	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
348	if (sna->mode.num_real_crtc)
349		return config->crtc[0];
350	else
351		return NULL;
352}
353
354#ifndef NDEBUG
355static void gem_close(int fd, uint32_t handle);
356static void assert_scanout(struct kgem *kgem, struct kgem_bo *bo,
357			   int width, int height)
358{
359	struct drm_mode_fb_cmd info;
360
361	assert(bo->scanout);
362
363	VG_CLEAR(info);
364	info.fb_id = fb_id(bo);
365
366	assert(drmIoctl(kgem->fd, DRM_IOCTL_MODE_GETFB, &info) == 0);
367	gem_close(kgem->fd, info.handle);
368
369	assert(width == info.width && height == info.height);
370}
371#else
372#define assert_scanout(k, b, w, h)
373#endif
374
375static unsigned get_fb(struct sna *sna, struct kgem_bo *bo,
376		       int width, int height)
377{
378	ScrnInfoPtr scrn = sna->scrn;
379	struct drm_mode_fb_cmd arg;
380
381	assert(bo->refcnt);
382	assert(bo->proxy == NULL);
383	assert(!bo->snoop);
384	assert(8*bo->pitch >= width * scrn->bitsPerPixel);
385	assert(height * bo->pitch <= kgem_bo_size(bo)); /* XXX crtc offset */
386	if (fb_id(bo)) {
387		DBG(("%s: reusing fb=%d for handle=%d\n",
388		     __FUNCTION__, fb_id(bo), bo->handle));
389		assert_scanout(&sna->kgem, bo, width, height);
390		return fb_id(bo);
391	}
392
393	DBG(("%s: create fb %dx%d@%d/%d\n",
394	     __FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel));
395
396	assert(bo->tiling != I915_TILING_Y);
397	assert((bo->pitch & 63) == 0);
398
399	VG_CLEAR(arg);
400	arg.width = width;
401	arg.height = height;
402	arg.pitch = bo->pitch;
403	arg.bpp = scrn->bitsPerPixel;
404	arg.depth = scrn->depth;
405	arg.handle = bo->handle;
406
407	assert(sna->scrn->vtSema); /* must be master */
408	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_ADDFB, &arg)) {
409		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
410			   "%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d: %d\n",
411			   __FUNCTION__, width, height,
412			   scrn->depth, scrn->bitsPerPixel, bo->pitch, errno);
413		return 0;
414	}
415	assert(arg.fb_id != 0);
416
417	DBG(("%s: attached fb=%d to handle=%d\n",
418	     __FUNCTION__, arg.fb_id, arg.handle));
419
420	bo->scanout = true;
421	return bo->delta = arg.fb_id;
422}
423
424static uint32_t gem_create(int fd, int size)
425{
426	struct drm_i915_gem_create create;
427
428	assert((size & 4095) == 0);
429
430	VG_CLEAR(create);
431	create.handle = 0;
432	create.size = size;
433	(void)drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
434
435	return create.handle;
436}
437
438static void *gem_mmap(int fd, int handle, int size)
439{
440	struct drm_i915_gem_mmap_gtt mmap_arg;
441	void *ptr;
442
443	VG_CLEAR(mmap_arg);
444	mmap_arg.handle = handle;
445	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg))
446		return NULL;
447
448	ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_arg.offset);
449	if (ptr == MAP_FAILED)
450		return NULL;
451
452	return ptr;
453}
454
455static void gem_close(int fd, uint32_t handle)
456{
457	struct drm_gem_close close;
458
459	VG_CLEAR(close);
460	close.handle = handle;
461	(void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &close);
462}
463
464#define BACKLIGHT_NAME             "Backlight"
465#define BACKLIGHT_DEPRECATED_NAME  "BACKLIGHT"
466static Atom backlight_atom, backlight_deprecated_atom;
467
468#if HAVE_UDEV
469static void
470sna_backlight_uevent(int fd, void *closure)
471{
472	struct sna *sna = closure;
473	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
474	int i;
475
476	DBG(("%s()\n", __FUNCTION__));
477
478	/* Drain the event queue */
479	while (event_pending(fd)) {
480		struct udev_device *dev;
481
482		DBG(("%s: waiting for uevent\n", __FUNCTION__));
483		dev = udev_monitor_receive_device(sna->mode.backlight_monitor);
484		if (dev == NULL)
485			break;
486
487		udev_device_unref(dev);
488	}
489
490	/* Query all backlights for any changes */
491	DBG(("%s: probing backlights for changes\n", __FUNCTION__));
492	for (i = 0; i < sna->mode.num_real_output; i++) {
493		xf86OutputPtr output = config->output[i];
494		struct sna_output *sna_output = to_sna_output(output);
495		int val;
496
497		if (sna_output->dpms_mode != DPMSModeOn)
498			continue;
499
500		assert(output->randr_output);
501
502		val = backlight_get(&sna_output->backlight);
503		if (val < 0)
504			continue;
505		DBG(("%s(%s): backlight '%s' was %d, now %d\n",
506		     __FUNCTION__, output->name, sna_output->backlight.iface,
507		     sna_output->backlight_active_level, val));
508
509		if (val == sna_output->backlight_active_level)
510			continue;
511
512		sna_output->backlight_active_level = val;
513
514		if (output->randr_output) {
515			DBG(("%s(%s): sending change notification\n", __FUNCTION__, output->name));
516			RRChangeOutputProperty(output->randr_output,
517					       backlight_atom, XA_INTEGER,
518					       32, PropModeReplace, 1, &val,
519					       TRUE, FALSE);
520			RRChangeOutputProperty(output->randr_output,
521					       backlight_deprecated_atom, XA_INTEGER,
522					       32, PropModeReplace, 1, &val,
523					       TRUE, FALSE);
524		}
525	}
526}
527
528static void sna_backlight_pre_init(struct sna *sna)
529{
530	struct udev *u;
531	struct udev_monitor *mon;
532
533#if !USE_BACKLIGHT
534	return;
535#endif
536
537	u = udev_new();
538	if (!u)
539		return;
540
541	mon = udev_monitor_new_from_netlink(u, "udev");
542	if (!mon)
543		goto free_udev;
544
545	if (udev_monitor_filter_add_match_subsystem_devtype(mon, "backlight", NULL))
546		goto free_monitor;
547
548	if (udev_monitor_enable_receiving(mon))
549		goto free_monitor;
550
551	sna->mode.backlight_handler =
552		xf86AddGeneralHandler(udev_monitor_get_fd(mon),
553				      sna_backlight_uevent, sna);
554	if (!sna->mode.backlight_handler)
555		goto free_monitor;
556
557	DBG(("%s: installed backlight monitor\n", __FUNCTION__));
558	sna->mode.backlight_monitor = mon;
559
560	return;
561
562free_monitor:
563	udev_monitor_unref(mon);
564free_udev:
565	udev_unref(u);
566}
567
568static void sna_backlight_drain_uevents(struct sna *sna)
569{
570	if (sna->mode.backlight_monitor == NULL)
571		return;
572
573	sna_backlight_uevent(udev_monitor_get_fd(sna->mode.backlight_monitor),
574			     sna);
575}
576
577static void sna_backlight_close(struct sna *sna)
578{
579	struct udev *u;
580
581	if (sna->mode.backlight_handler == NULL)
582		return;
583
584	xf86RemoveGeneralHandler(sna->mode.backlight_handler);
585
586	u = udev_monitor_get_udev(sna->mode.backlight_monitor);
587	udev_monitor_unref(sna->mode.backlight_monitor);
588	udev_unref(u);
589
590	sna->mode.backlight_handler = NULL;
591	sna->mode.backlight_monitor = NULL;
592}
593#else
594static void sna_backlight_pre_init(struct sna *sna) { }
595static void sna_backlight_drain_uevents(struct sna *sna) { }
596static void sna_backlight_close(struct sna *sna) { }
597#endif
598
599static void
600sna_output_backlight_disable(struct sna_output *sna_output)
601{
602	xf86OutputPtr output = sna_output->base;
603
604	xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
605		   "Failed to set backlight %s for output %s, disabling\n",
606		   sna_output->backlight.iface, output->name);
607	backlight_disable(&sna_output->backlight);
608	if (output->randr_output) {
609		RRDeleteOutputProperty(output->randr_output, backlight_atom);
610		RRDeleteOutputProperty(output->randr_output, backlight_deprecated_atom);
611	}
612}
613
614static int
615sna_output_backlight_set(struct sna_output *sna_output, int level)
616{
617	int ret = 0;
618
619	DBG(("%s(%s) level=%d, max=%d\n", __FUNCTION__,
620	     sna_output->base->name, level, sna_output->backlight.max));
621
622	if (backlight_set(&sna_output->backlight, level)) {
623		sna_output_backlight_disable(sna_output);
624		ret = -1;
625	}
626
627	/* Consume the uevent notification now so that we don't misconstrue
628	 * the change latter when we wake up and the output is in a different
629	 * state.
630	 */
631	sna_backlight_drain_uevents(to_sna(sna_output->base->scrn));
632	return ret;
633}
634
635static void
636sna_output_backlight_off(struct sna_output *sna_output)
637{
638	DBG(("%s(%s)\n", __FUNCTION__, sna_output->base->name));
639	backlight_off(&sna_output->backlight);
640	sna_output_backlight_set(sna_output, 0);
641}
642
643static void
644sna_output_backlight_on(struct sna_output *sna_output)
645{
646	DBG(("%s(%s)\n", __FUNCTION__, sna_output->base->name));
647	sna_output_backlight_set(sna_output,
648				 sna_output->backlight_active_level);
649	if (backlight_on(&sna_output->backlight) < 0)
650		sna_output_backlight_disable(sna_output);
651}
652
653static int
654sna_output_backlight_get(xf86OutputPtr output)
655{
656	struct sna_output *sna_output = output->driver_private;
657	int level = backlight_get(&sna_output->backlight);
658	DBG(("%s(%s) level=%d, max=%d\n", __FUNCTION__,
659	     output->name, level, sna_output->backlight.max));
660	return level;
661}
662
663static char *
664has_user_backlight_override(xf86OutputPtr output)
665{
666	struct sna *sna = to_sna(output->scrn);
667	const char *str;
668
669	str = xf86GetOptValString(sna->Options, OPTION_BACKLIGHT);
670	if (str == NULL)
671		return NULL;
672
673	DBG(("%s(%s) requested %s\n", __FUNCTION__, output->name, str));
674	if (*str == '\0')
675		return (char *)str;
676
677	if (backlight_exists(str) == BL_NONE) {
678		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
679			   "Unrecognised backlight control interface '%s'\n",
680			   str);
681		return NULL;
682	}
683
684	return strdup(str);
685}
686
687static void
688sna_output_backlight_init(xf86OutputPtr output)
689{
690	struct sna_output *sna_output = output->driver_private;
691	struct pci_device *pci;
692	MessageType from;
693	char *best_iface;
694
695#if !USE_BACKLIGHT
696	return;
697#endif
698
699	from = X_CONFIG;
700	best_iface = has_user_backlight_override(output);
701	if (best_iface)
702		goto done;
703
704	/* XXX detect right backlight for multi-GPU/panels */
705	from = X_PROBED;
706	pci = xf86GetPciInfoForEntity(to_sna(output->scrn)->pEnt->index);
707	if (pci != NULL)
708		best_iface = backlight_find_for_device(pci);
709
710done:
711	DBG(("%s(%s) opening backlight %s\n", __FUNCTION__,
712	     output->name, best_iface ?: "none"));
713	sna_output->backlight_active_level =
714		backlight_open(&sna_output->backlight, best_iface);
715	DBG(("%s(%s): initial backlight value %d\n",
716	     __FUNCTION__, output->name, sna_output->backlight_active_level));
717	if (sna_output->backlight_active_level < 0)
718		return;
719
720	switch (sna_output->backlight.type) {
721	case BL_FIRMWARE: best_iface = (char *)"firmware"; break;
722	case BL_PLATFORM: best_iface = (char *)"platform"; break;
723	case BL_RAW: best_iface = (char *)"raw"; break;
724	default: best_iface = (char *)"unknown"; break;
725	}
726	xf86DrvMsg(output->scrn->scrnIndex, from,
727		   "Found backlight control interface %s (type '%s') for output %s\n",
728		   sna_output->backlight.iface, best_iface, output->name);
729}
730
731static char *canonical_kmode_name(const struct drm_mode_modeinfo *kmode)
732{
733	char tmp[32], *buf;
734	int len;
735
736	len = sprintf(tmp, "%dx%d%s",
737		      kmode->hdisplay, kmode->vdisplay,
738		      kmode->flags & V_INTERLACE ? "i" : "");
739	if ((unsigned)len >= sizeof(tmp))
740		return NULL;
741
742	buf = malloc(len + 1);
743	if (buf == NULL)
744		return NULL;
745
746	return memcpy(buf, tmp, len + 1);
747}
748
749static char *get_kmode_name(const struct drm_mode_modeinfo *kmode)
750{
751	if (*kmode->name == '\0')
752		return canonical_kmode_name(kmode);
753
754	return strdup(kmode->name);
755}
756
757static DisplayModePtr
758mode_from_kmode(ScrnInfoPtr scrn,
759		const struct drm_mode_modeinfo *kmode,
760		DisplayModePtr mode)
761{
762	DBG(("kmode: %s, clock=%d, %d %d %d %d %d, %d %d %d %d %d, flags=%x, type=%x\n",
763	     kmode->name, kmode->clock,
764	     kmode->hdisplay, kmode->hsync_start, kmode->hsync_end, kmode->htotal, kmode->hskew,
765	     kmode->vdisplay, kmode->vsync_start, kmode->vsync_end, kmode->vtotal, kmode->vscan,
766	     kmode->flags, kmode->type));
767
768	mode->status = MODE_OK;
769
770	mode->Clock = kmode->clock;
771
772	mode->HDisplay = kmode->hdisplay;
773	mode->HSyncStart = kmode->hsync_start;
774	mode->HSyncEnd = kmode->hsync_end;
775	mode->HTotal = kmode->htotal;
776	mode->HSkew = kmode->hskew;
777
778	mode->VDisplay = kmode->vdisplay;
779	mode->VSyncStart = kmode->vsync_start;
780	mode->VSyncEnd = kmode->vsync_end;
781	mode->VTotal = kmode->vtotal;
782	mode->VScan = kmode->vscan;
783
784	mode->Flags = kmode->flags;
785	mode->name = get_kmode_name(kmode);
786
787	if (kmode->type & DRM_MODE_TYPE_DRIVER)
788		mode->type = M_T_DRIVER;
789	if (kmode->type & DRM_MODE_TYPE_PREFERRED)
790		mode->type |= M_T_PREFERRED;
791
792	if (mode->status == MODE_OK && kmode->flags & ~KNOWN_MODE_FLAGS)
793		mode->status = MODE_BAD; /* unknown flags => unhandled */
794
795	xf86SetModeCrtc(mode, scrn->adjustFlags);
796	return mode;
797}
798
799static void
800mode_to_kmode(struct drm_mode_modeinfo *kmode, DisplayModePtr mode)
801{
802	memset(kmode, 0, sizeof(*kmode));
803
804	kmode->clock = mode->Clock;
805	kmode->hdisplay = mode->HDisplay;
806	kmode->hsync_start = mode->HSyncStart;
807	kmode->hsync_end = mode->HSyncEnd;
808	kmode->htotal = mode->HTotal;
809	kmode->hskew = mode->HSkew;
810
811	kmode->vdisplay = mode->VDisplay;
812	kmode->vsync_start = mode->VSyncStart;
813	kmode->vsync_end = mode->VSyncEnd;
814	kmode->vtotal = mode->VTotal;
815	kmode->vscan = mode->VScan;
816
817	kmode->flags = mode->Flags;
818	if (mode->name)
819		strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
820	kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
821}
822
823static void
824sna_crtc_force_outputs_on(xf86CrtcPtr crtc)
825{
826	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
827	int i;
828
829	assert(to_sna_crtc(crtc));
830	DBG(("%s(pipe=%d), currently? %d\n", __FUNCTION__,
831	     to_sna_crtc(crtc)->pipe, to_sna_crtc(crtc)->dpms_mode));
832
833	/* DPMS handling by the kernel is inconsistent, so after setting a
834	 * mode on an output presume that we intend for it to be on, or that
835	 * the kernel will force it on.
836	 *
837	 * So force DPMS to be on for all connected outputs, and restore
838	 * the backlight.
839	 */
840	for (i = 0; i < config->num_output; i++) {
841		xf86OutputPtr output = config->output[i];
842
843		if (output->crtc != crtc)
844			continue;
845
846		output->funcs->dpms(output, DPMSModeOn);
847	}
848
849	to_sna_crtc(crtc)->dpms_mode = DPMSModeOn;
850#if XF86_CRTC_VERSION >= 3
851	crtc->active = TRUE;
852#endif
853}
854
855static void
856sna_crtc_force_outputs_off(xf86CrtcPtr crtc)
857{
858	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
859	int i;
860
861	assert(to_sna_crtc(crtc));
862	DBG(("%s(pipe=%d), currently? %d\n", __FUNCTION__,
863	     to_sna_crtc(crtc)->pipe, to_sna_crtc(crtc)->dpms_mode));
864
865	/* DPMS handling by the kernel is inconsistent, so after setting a
866	 * mode on an output presume that we intend for it to be on, or that
867	 * the kernel will force it on.
868	 *
869	 * So force DPMS to be on for all connected outputs, and restore
870	 * the backlight.
871	 */
872	for (i = 0; i < config->num_output; i++) {
873		xf86OutputPtr output = config->output[i];
874
875		if (output->crtc != crtc)
876			continue;
877
878		output->funcs->dpms(output, DPMSModeOff);
879	}
880
881	to_sna_crtc(crtc)->dpms_mode = DPMSModeOff;
882}
883
884static unsigned
885rotation_reduce(struct plane *p, unsigned rotation)
886{
887	unsigned unsupported_rotations = rotation & ~p->rotation.supported;
888
889	if (unsupported_rotations == 0)
890		return rotation;
891
892#define RR_Reflect_XY (RR_Reflect_X | RR_Reflect_Y)
893
894	if ((unsupported_rotations & RR_Reflect_XY) == RR_Reflect_XY &&
895	    p->rotation.supported& RR_Rotate_180) {
896		rotation &= ~RR_Reflect_XY;
897		rotation ^= RR_Rotate_180;
898	}
899
900	if ((unsupported_rotations & RR_Rotate_180) &&
901	    (p->rotation.supported& RR_Reflect_XY) == RR_Reflect_XY) {
902		rotation ^= RR_Reflect_XY;
903		rotation &= ~RR_Rotate_180;
904	}
905
906#undef RR_Reflect_XY
907
908	return rotation;
909}
910
911static bool
912rotation_set(struct sna *sna, struct plane *p, uint32_t desired)
913{
914#define LOCAL_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xbA, struct local_mode_obj_set_property)
915	struct local_mode_obj_set_property {
916		uint64_t value;
917		uint32_t prop_id;
918		uint32_t obj_id;
919		uint32_t obj_type;
920		uint32_t pad;
921	} prop;
922
923	if (desired == p->rotation.current)
924		return true;
925
926	if ((desired & p->rotation.supported) == 0) {
927		errno = EINVAL;
928		return false;
929	}
930
931	DBG(("%s: obj=%d, type=%x prop=%d set-rotation=%x\n",
932	     __FUNCTION__, p->id, LOCAL_MODE_OBJECT_PLANE, p->rotation.prop, desired));
933
934	assert(p->id);
935	assert(p->rotation.prop);
936
937	VG_CLEAR(prop);
938	prop.obj_id = p->id;
939	prop.obj_type = LOCAL_MODE_OBJECT_PLANE;
940	prop.prop_id = p->rotation.prop;
941	prop.value = desired;
942
943	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_SETPROPERTY, &prop))
944		return false;
945
946	p->rotation.current = desired;
947	return true;
948}
949
950static void
951rotation_reset(struct plane *p)
952{
953	if (p->rotation.prop == 0)
954		return;
955
956	p->rotation.current = 0;
957}
958
959bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation)
960{
961	assert(to_sna_crtc(crtc));
962	DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n",
963	     __FUNCTION__,
964	     to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe, to_sna_crtc(crtc)->sprite.id,
965	     rotation));
966
967	return rotation_set(to_sna(crtc->scrn),
968			    &to_sna_crtc(crtc)->sprite,
969			    rotation_reduce(&to_sna_crtc(crtc)->sprite, rotation));
970}
971
972static bool
973sna_crtc_apply(xf86CrtcPtr crtc)
974{
975	struct sna *sna = to_sna(crtc->scrn);
976	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
977	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
978	struct drm_mode_crtc arg;
979	uint32_t output_ids[32];
980	int output_count = 0;
981	int i;
982
983	DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->bo->handle));
984	if (!sna_crtc->kmode.clock) {
985		ERR(("%s(CRTC:%d [pipe=%d]): attempted to set an invalid mode\n",
986		     __FUNCTION__, sna_crtc->id, sna_crtc->pipe));
987		return false;
988	}
989
990	assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids));
991	sna_crtc_disable_cursor(sna, sna_crtc);
992
993	if (!rotation_set(sna, &sna_crtc->primary, sna_crtc->rotation)) {
994		ERR(("%s: set-primary-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n",
995		     __FUNCTION__, sna_crtc->primary.rotation.prop, sna_crtc->rotation, sna_crtc->id, sna_crtc->pipe, errno));
996		sna_crtc->primary.rotation.supported &= ~sna_crtc->rotation;
997		return false;
998	}
999	DBG(("%s: CRTC:%d [pipe=%d] primary rotation set to %x\n",
1000	     __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->rotation));
1001
1002	for (i = 0; i < sna->mode.num_real_output; i++) {
1003		xf86OutputPtr output = config->output[i];
1004
1005		/* Make sure we mark the output as off (and save the backlight)
1006		 * before the kernel turns it off due to changing the pipe.
1007		 * This is necessary as the kernel may turn off the backlight
1008		 * and we lose track of the user settings.
1009		 */
1010		if (output->crtc == NULL)
1011			output->funcs->dpms(output, DPMSModeOff);
1012
1013		if (output->crtc != crtc)
1014			continue;
1015
1016		/* Skip over any hotunplugged outputs so that we can
1017		 * recover in cases where the previous mode is now
1018		 * only partially valid.
1019		 */
1020		if (!to_sna_output(output)->id)
1021			continue;
1022
1023		DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n",
1024		     __FUNCTION__, output->name, i, to_connector_id(output),
1025		     sna_crtc->id, sna_crtc->pipe,
1026		     (uint32_t)output->possible_crtcs,
1027		     (uint32_t)output->possible_clones));
1028
1029		assert(output->possible_crtcs & (1 << sna_crtc->pipe) ||
1030		       is_zaphod(crtc->scrn));
1031
1032		output_ids[output_count] = to_connector_id(output);
1033		if (++output_count == ARRAY_SIZE(output_ids)) {
1034			DBG(("%s: too many outputs (%d) for me!\n",
1035			     __FUNCTION__, output_count));
1036			errno = EINVAL;
1037			return false;
1038		}
1039	}
1040	if (output_count == 0) {
1041		DBG(("%s: no outputs\n", __FUNCTION__));
1042		errno = EINVAL;
1043		return false;
1044	}
1045
1046	VG_CLEAR(arg);
1047	arg.crtc_id = sna_crtc->id;
1048	arg.fb_id = fb_id(sna_crtc->bo);
1049	if (sna_crtc->transform || sna_crtc->slave_pixmap) {
1050		arg.x = 0;
1051		arg.y = 0;
1052		sna_crtc->offset = 0;
1053	} else {
1054		arg.x = crtc->x;
1055		arg.y = crtc->y;
1056		sna_crtc->offset = arg.y << 16 | arg.x;
1057	}
1058	arg.set_connectors_ptr = (uintptr_t)output_ids;
1059	arg.count_connectors = output_count;
1060	arg.mode = sna_crtc->kmode;
1061	arg.mode_valid = 1;
1062
1063	DBG(("%s: applying crtc [%d, pipe=%d] mode=%dx%d+%d+%d@%d, fb=%d%s%s update to %d outputs [%d...]\n",
1064	     __FUNCTION__, sna_crtc->id, sna_crtc->pipe,
1065	     arg.mode.hdisplay,
1066	     arg.mode.vdisplay,
1067	     arg.x, arg.y,
1068	     arg.mode.clock,
1069	     arg.fb_id,
1070	     sna_crtc->shadow ? " [shadow]" : "",
1071	     sna_crtc->transform ? " [transformed]" : "",
1072	     output_count, output_count ? output_ids[0] : 0));
1073
1074	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg))
1075		return false;
1076
1077	sna_crtc->mode_serial++;
1078	sna_crtc_force_outputs_on(crtc);
1079	return true;
1080}
1081
1082static bool overlap(const BoxRec *a, const BoxRec *b)
1083{
1084	if (a->x1 >= b->x2)
1085		return false;
1086	if (a->x2 <= b->x1)
1087		return false;
1088
1089	if (a->y1 >= b->y2)
1090		return false;
1091	if (a->y2 <= b->y1)
1092		return false;
1093
1094	return true;
1095}
1096
1097static bool wait_for_shadow(struct sna *sna,
1098			    struct sna_pixmap *priv,
1099			    unsigned flags)
1100{
1101	PixmapPtr pixmap = priv->pixmap;
1102	DamagePtr damage;
1103	struct kgem_bo *bo, *tmp;
1104	int flip_active;
1105	bool ret = true;
1106
1107	DBG(("%s: flags=%x, flips=%d, handle=%d, shadow=%d\n",
1108	     __FUNCTION__, flags, sna->mode.flip_active,
1109	     priv->gpu_bo->handle, sna->mode.shadow->handle));
1110
1111	assert(priv->move_to_gpu_data == sna);
1112	assert(sna->mode.shadow != priv->gpu_bo);
1113
1114	if (flags == 0 || pixmap != sna->front || !sna->mode.shadow_damage)
1115		goto done;
1116
1117	if ((flags & MOVE_WRITE) == 0) {
1118		if ((flags & __MOVE_SCANOUT) == 0) {
1119			struct sna_crtc *crtc;
1120
1121			list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link) {
1122				if (overlap(&sna->mode.shadow_region.extents,
1123					    &crtc->base->bounds)) {
1124					DrawableRec draw;
1125					RegionRec region;
1126
1127					draw.width = crtc->base->mode.HDisplay;
1128					draw.height = crtc->base->mode.VDisplay;
1129					draw.depth = sna->front->drawable.depth;
1130					draw.bitsPerPixel = sna->front->drawable.bitsPerPixel;
1131
1132					DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n",
1133					     __FUNCTION__,
1134					     crtc->base->bounds.x1,
1135					     crtc->base->bounds.y1,
1136					     crtc->base->bounds.x2,
1137					     crtc->base->bounds.y2,
1138					     crtc->client_bo->handle));
1139
1140					ret &= sna->render.copy_boxes(sna, GXcopy,
1141								      &draw, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
1142								      &pixmap->drawable, priv->gpu_bo, 0, 0,
1143								      &crtc->base->bounds, 1,
1144								      0);
1145
1146					region.extents = crtc->base->bounds;
1147					region.data = NULL;
1148					RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, &region);
1149				}
1150			}
1151		}
1152
1153		return ret;
1154	}
1155
1156	assert(sna->mode.shadow_active);
1157
1158	damage = sna->mode.shadow_damage;
1159	sna->mode.shadow_damage = NULL;
1160
1161	flip_active = sna->mode.flip_active;
1162	if (flip_active) {
1163		struct sna_crtc *crtc;
1164		list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link)
1165			flip_active -= crtc->flip_pending;
1166		DBG(("%s: %d flips still pending, shadow flip_active=%d\n",
1167		     __FUNCTION__, sna->mode.flip_active, flip_active));
1168	}
1169	if (flip_active) {
1170		/* raw cmd to avoid setting wedged in the middle of an op */
1171		drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_THROTTLE, 0);
1172		sna->kgem.need_throttle = false;
1173
1174		while (flip_active && sna_mode_wakeup(sna)) {
1175			struct sna_crtc *crtc;
1176
1177			flip_active = sna->mode.flip_active;
1178			list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link)
1179				flip_active -= crtc->flip_pending;
1180		}
1181		DBG(("%s: after waiting %d flips outstanding, flip_active=%d\n",
1182		     __FUNCTION__, sna->mode.flip_active, flip_active));
1183	}
1184
1185	bo = sna->mode.shadow;
1186	if (flip_active) {
1187		bo = kgem_create_2d(&sna->kgem,
1188				    pixmap->drawable.width,
1189				    pixmap->drawable.height,
1190				    pixmap->drawable.bitsPerPixel,
1191				    priv->gpu_bo->tiling,
1192				    CREATE_EXACT | CREATE_SCANOUT);
1193		if (bo != NULL) {
1194			DBG(("%s: replacing still-attached GPU bo handle=%d, flips=%d\n",
1195			     __FUNCTION__, priv->gpu_bo->tiling, sna->mode.flip_active));
1196
1197			RegionUninit(&sna->mode.shadow_region);
1198			sna->mode.shadow_region.extents.x1 = 0;
1199			sna->mode.shadow_region.extents.y1 = 0;
1200			sna->mode.shadow_region.extents.x2 = pixmap->drawable.width;
1201			sna->mode.shadow_region.extents.y2 = pixmap->drawable.height;
1202			sna->mode.shadow_region.data = NULL;
1203		} else {
1204			while (sna->mode.flip_active &&
1205			       sna_mode_wait_for_event(sna))
1206				sna_mode_wakeup(sna);
1207
1208			bo = sna->mode.shadow;
1209		}
1210	}
1211
1212	if (bo->refcnt > 1) {
1213		bo = kgem_create_2d(&sna->kgem,
1214				    pixmap->drawable.width,
1215				    pixmap->drawable.height,
1216				    pixmap->drawable.bitsPerPixel,
1217				    priv->gpu_bo->tiling,
1218				    CREATE_EXACT | CREATE_SCANOUT);
1219		if (bo != NULL) {
1220			DBG(("%s: replacing exported GPU bo\n",
1221			     __FUNCTION__));
1222
1223			RegionUninit(&sna->mode.shadow_region);
1224			sna->mode.shadow_region.extents.x1 = 0;
1225			sna->mode.shadow_region.extents.y1 = 0;
1226			sna->mode.shadow_region.extents.x2 = pixmap->drawable.width;
1227			sna->mode.shadow_region.extents.y2 = pixmap->drawable.height;
1228			sna->mode.shadow_region.data = NULL;
1229		} else
1230			bo = sna->mode.shadow;
1231	}
1232
1233	sna->mode.shadow_damage = damage;
1234
1235	RegionSubtract(&sna->mode.shadow_region,
1236		       &sna->mode.shadow_region,
1237		       &sna->mode.shadow_cancel);
1238
1239	while (!list_is_empty(&sna->mode.shadow_crtc)) {
1240		struct sna_crtc *crtc =
1241			list_first_entry(&sna->mode.shadow_crtc, struct sna_crtc, shadow_link);
1242		if (overlap(&crtc->base->bounds,
1243			    &sna->mode.shadow_region.extents)) {
1244			RegionRec region;
1245			DrawableRec draw;
1246
1247			draw.width = crtc->base->mode.HDisplay;
1248			draw.height = crtc->base->mode.VDisplay;
1249			draw.depth = sna->front->drawable.depth;
1250			draw.bitsPerPixel = sna->front->drawable.bitsPerPixel;
1251
1252			DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n",
1253			     __FUNCTION__,
1254			     crtc->base->bounds.x1,
1255			     crtc->base->bounds.y1,
1256			     crtc->base->bounds.x2,
1257			     crtc->base->bounds.y2,
1258			     crtc->client_bo->handle));
1259
1260			ret = sna->render.copy_boxes(sna, GXcopy,
1261						     &draw, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
1262						     &pixmap->drawable, bo, 0, 0,
1263						     &crtc->base->bounds, 1,
1264						     0);
1265
1266
1267			region.extents = crtc->base->bounds;
1268			region.data = NULL;
1269			RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, &region);
1270		}
1271
1272		kgem_bo_destroy(&sna->kgem, crtc->client_bo);
1273		crtc->client_bo = NULL;
1274		list_del(&crtc->shadow_link);
1275	}
1276
1277	if (RegionNotEmpty(&sna->mode.shadow_region)) {
1278		DBG(("%s: copying existing GPU damage: %dx(%d, %d), (%d, %d)\n",
1279		     __FUNCTION__, region_num_rects(&sna->mode.shadow_region),
1280		     sna->mode.shadow_region.extents.x1,
1281		     sna->mode.shadow_region.extents.y1,
1282		     sna->mode.shadow_region.extents.x2,
1283		     sna->mode.shadow_region.extents.y2));
1284		ret = sna->render.copy_boxes(sna, GXcopy,
1285					     &pixmap->drawable, priv->gpu_bo, 0, 0,
1286					     &pixmap->drawable, bo, 0, 0,
1287					     region_rects(&sna->mode.shadow_region),
1288					     region_num_rects(&sna->mode.shadow_region),
1289					     0);
1290	}
1291
1292	if (priv->cow)
1293		sna_pixmap_undo_cow(sna, priv, 0);
1294
1295	sna_pixmap_unmap(pixmap, priv);
1296
1297	DBG(("%s: setting front pixmap to handle=%d\n", __FUNCTION__, bo->handle));
1298	tmp = priv->gpu_bo;
1299	priv->gpu_bo = bo;
1300	if (bo != sna->mode.shadow)
1301		kgem_bo_destroy(&sna->kgem, sna->mode.shadow);
1302	sna->mode.shadow = tmp;
1303
1304	sna_dri2_pixmap_update_bo(sna, pixmap, bo);
1305
1306done:
1307	RegionEmpty(&sna->mode.shadow_cancel);
1308	RegionEmpty(&sna->mode.shadow_region);
1309	sna->mode.shadow_dirty = false;
1310
1311	priv->move_to_gpu_data = NULL;
1312	priv->move_to_gpu = NULL;
1313
1314	return ret;
1315}
1316
1317bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv,
1318				      const RegionRec *region)
1319{
1320	struct sna *sna;
1321
1322	if (priv->move_to_gpu != wait_for_shadow)
1323		return false;
1324
1325	sna = priv->move_to_gpu_data;
1326	if (region) {
1327		DBG(("%s: discarding region %dx[(%d, %d), (%d, %d)] from damage %dx[(%d, %d], (%d, %d)]\n",
1328		     __FUNCTION__,
1329		     region_num_rects(region),
1330		     region->extents.x1, region->extents.y1,
1331		     region->extents.x2, region->extents.y2,
1332		     region_num_rects(&sna->mode.shadow_region),
1333		     sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1,
1334		     sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2));
1335
1336		RegionSubtract(&sna->mode.shadow_region,
1337			       &sna->mode.shadow_region,
1338			       (RegionPtr)region);
1339		RegionUnion(&sna->mode.shadow_cancel,
1340			    &sna->mode.shadow_cancel,
1341			    (RegionPtr)region);
1342	} else {
1343		DBG(("%s: discarding all damage %dx[(%d, %d], (%d, %d)]\n",
1344		     __FUNCTION__,
1345		     region_num_rects(&sna->mode.shadow_region),
1346		     sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1,
1347		     sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2));
1348		RegionEmpty(&sna->mode.shadow_region);
1349
1350		RegionUninit(&sna->mode.shadow_cancel);
1351		sna->mode.shadow_cancel.extents.x1 = 0;
1352		sna->mode.shadow_cancel.extents.y1 = 0;
1353		sna->mode.shadow_cancel.extents.x2 = sna->front->drawable.width;
1354		sna->mode.shadow_cancel.extents.y2 = sna->front->drawable.height;
1355		sna->mode.shadow_cancel.data = NULL;
1356	}
1357
1358	return RegionNil(&sna->mode.shadow_region);
1359}
1360
1361static bool sna_mode_enable_shadow(struct sna *sna)
1362{
1363	ScreenPtr screen = sna->scrn->pScreen;
1364
1365	DBG(("%s\n", __FUNCTION__));
1366	assert(sna->mode.shadow == NULL);
1367	assert(sna->mode.shadow_damage == NULL);
1368	assert(sna->mode.shadow_active == 0);
1369
1370	sna->mode.shadow_damage = DamageCreate(NULL, NULL,
1371					       DamageReportNone, TRUE,
1372					       screen, screen);
1373	if (!sna->mode.shadow_damage)
1374		return false;
1375
1376	DamageRegister(&sna->front->drawable, sna->mode.shadow_damage);
1377	return true;
1378}
1379
1380static void sna_mode_disable_shadow(struct sna *sna)
1381{
1382	struct sna_pixmap *priv;
1383
1384	if (!sna->mode.shadow_damage)
1385		return;
1386
1387	DBG(("%s\n", __FUNCTION__));
1388
1389	priv = sna_pixmap(sna->front);
1390	if (priv->move_to_gpu == wait_for_shadow)
1391		priv->move_to_gpu(sna, priv, 0);
1392
1393	DamageUnregister(&sna->front->drawable, sna->mode.shadow_damage);
1394	DamageDestroy(sna->mode.shadow_damage);
1395	sna->mode.shadow_damage = NULL;
1396
1397	if (sna->mode.shadow) {
1398		kgem_bo_destroy(&sna->kgem, sna->mode.shadow);
1399		sna->mode.shadow = NULL;
1400	}
1401
1402	assert(sna->mode.shadow_active == 0);
1403	sna->mode.shadow_dirty = false;
1404}
1405
1406static void sna_crtc_slave_damage(DamagePtr damage, RegionPtr region, void *closure)
1407{
1408	struct sna_crtc *crtc = closure;
1409	struct sna *sna = to_sna(crtc->base->scrn);
1410	RegionPtr scr;
1411
1412	DBG(("%s: pushing damage [(%d, %d), (%d, %d) x %d] to CRTC [pipe=%d] (%d, %d)\n",
1413	     __FUNCTION__,
1414	     region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2,
1415	     region_num_rects(region),
1416	     crtc->pipe, crtc->base->x, crtc->base->y));
1417
1418	assert(crtc->slave_damage == damage);
1419	assert(sna->mode.shadow_damage);
1420
1421	RegionTranslate(region, crtc->base->x, crtc->base->y);
1422	scr = DamageRegion(sna->mode.shadow_damage);
1423	RegionUnion(scr, scr, region);
1424	RegionTranslate(region, -crtc->base->x, -crtc->base->y);
1425}
1426
1427static bool sna_crtc_enable_shadow(struct sna *sna, struct sna_crtc *crtc)
1428{
1429	if (crtc->shadow) {
1430		assert(sna->mode.shadow_damage && sna->mode.shadow_active);
1431		return true;
1432	}
1433
1434	DBG(("%s: enabling for crtc %d\n", __FUNCTION__, crtc->id));
1435
1436	if (!sna->mode.shadow_active) {
1437		if (!sna_mode_enable_shadow(sna))
1438			return false;
1439		assert(sna->mode.shadow_damage);
1440		assert(sna->mode.shadow == NULL);
1441	}
1442
1443	if (crtc->slave_pixmap) {
1444		assert(crtc->slave_damage == NULL);
1445
1446		crtc->slave_damage = DamageCreate(sna_crtc_slave_damage, NULL,
1447						  DamageReportRawRegion, TRUE,
1448						  sna->scrn->pScreen, crtc);
1449		if (crtc->slave_damage == NULL) {
1450			if (!--sna->mode.shadow_active)
1451				sna_mode_disable_shadow(sna);
1452			return false;
1453		}
1454
1455		DamageRegister(&crtc->slave_pixmap->drawable, crtc->slave_damage);
1456	}
1457
1458	crtc->shadow = true;
1459	sna->mode.shadow_active++;
1460	return true;
1461}
1462
1463static void sna_crtc_disable_override(struct sna *sna, struct sna_crtc *crtc)
1464{
1465	if (crtc->client_bo == NULL)
1466		return;
1467
1468	if (!crtc->transform) {
1469		DrawableRec tmp;
1470
1471		tmp.width = crtc->base->mode.HDisplay;
1472		tmp.height = crtc->base->mode.VDisplay;
1473		tmp.depth = sna->front->drawable.depth;
1474		tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
1475
1476		sna->render.copy_boxes(sna, GXcopy,
1477				       &tmp, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
1478				       &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0,
1479				       &crtc->base->bounds, 1, 0);
1480		list_del(&crtc->shadow_link);
1481	}
1482	kgem_bo_destroy(&sna->kgem, crtc->client_bo);
1483	crtc->client_bo = NULL;
1484}
1485
1486static void sna_crtc_disable_shadow(struct sna *sna, struct sna_crtc *crtc)
1487{
1488	crtc->fallback_shadow = false;
1489	if (!crtc->shadow)
1490		return;
1491
1492	DBG(("%s: disabling for crtc %d\n", __FUNCTION__, crtc->id));
1493	assert(sna->mode.shadow_active > 0);
1494
1495	if (crtc->slave_damage) {
1496		assert(crtc->slave_pixmap);
1497		DamageUnregister(&crtc->slave_pixmap->drawable, crtc->slave_damage);
1498		DamageDestroy(crtc->slave_damage);
1499		crtc->slave_damage = NULL;
1500	}
1501
1502	sna_crtc_disable_override(sna, crtc);
1503
1504	if (!--sna->mode.shadow_active)
1505		sna_mode_disable_shadow(sna);
1506
1507	crtc->shadow = false;
1508}
1509
1510static void
1511__sna_crtc_disable(struct sna *sna, struct sna_crtc *sna_crtc)
1512{
1513	sna_crtc->mode_serial++;
1514
1515	sna_crtc_disable_cursor(sna, sna_crtc);
1516	rotation_set(sna, &sna_crtc->primary, RR_Rotate_0);
1517	sna_crtc_disable_shadow(sna, sna_crtc);
1518
1519	if (sna_crtc->bo) {
1520		assert(sna_crtc->bo->active_scanout);
1521		assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout);
1522		sna_crtc->bo->active_scanout--;
1523		kgem_bo_destroy(&sna->kgem, sna_crtc->bo);
1524		sna_crtc->bo = NULL;
1525
1526		assert(sna->mode.front_active);
1527		sna->mode.front_active--;
1528		sna->mode.dirty = true;
1529	}
1530
1531	if (sna_crtc->shadow_bo) {
1532		kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo);
1533		sna_crtc->shadow_bo = NULL;
1534	}
1535	sna_crtc->transform = false;
1536
1537	assert(!sna_crtc->shadow);
1538}
1539
1540static void
1541sna_crtc_disable(xf86CrtcPtr crtc)
1542{
1543	struct sna *sna = to_sna(crtc->scrn);
1544	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
1545	struct drm_mode_crtc arg;
1546
1547	if (sna_crtc == NULL)
1548		return;
1549
1550	DBG(("%s: disabling crtc [%d, pipe=%d]\n", __FUNCTION__,
1551	     sna_crtc->id, sna_crtc->pipe));
1552
1553	sna_crtc_force_outputs_off(crtc);
1554	assert(sna_crtc->dpms_mode == DPMSModeOff);
1555
1556	memset(&arg, 0, sizeof(arg));
1557	arg.crtc_id = sna_crtc->id;
1558	(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
1559
1560	__sna_crtc_disable(sna, sna_crtc);
1561}
1562
1563static void update_flush_interval(struct sna *sna)
1564{
1565	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
1566	int i, max_vrefresh = 0;
1567
1568	DBG(("%s: front_active=%d\n", __FUNCTION__, sna->mode.front_active));
1569
1570	for (i = 0; i < sna->mode.num_real_crtc; i++) {
1571		xf86CrtcPtr crtc = config->crtc[i];
1572
1573		assert(to_sna_crtc(crtc) != NULL);
1574
1575		if (!crtc->enabled) {
1576			DBG(("%s: CRTC:%d (pipe %d) disabled\n",
1577			     __FUNCTION__,i, to_sna_crtc(crtc)->pipe));
1578			assert(to_sna_crtc(crtc)->bo == NULL);
1579			continue;
1580		}
1581
1582		if (to_sna_crtc(crtc)->dpms_mode != DPMSModeOn) {
1583			DBG(("%s: CRTC:%d (pipe %d) turned off\n",
1584			     __FUNCTION__,i, to_sna_crtc(crtc)->pipe));
1585			continue;
1586		}
1587
1588		DBG(("%s: CRTC:%d (pipe %d) vrefresh=%f\n",
1589		     __FUNCTION__, i, to_sna_crtc(crtc)->pipe,
1590		     xf86ModeVRefresh(&crtc->mode)));
1591		max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(&crtc->mode));
1592	}
1593
1594	if (max_vrefresh == 0) {
1595		assert(sna->mode.front_active == 0);
1596		sna->vblank_interval = 0;
1597	} else
1598		sna->vblank_interval = 1000 / max_vrefresh; /* Hz -> ms */
1599
1600	DBG(("max_vrefresh=%d, vblank_interval=%d ms\n",
1601	       max_vrefresh, sna->vblank_interval));
1602}
1603
1604static struct kgem_bo *sna_create_bo_for_fbcon(struct sna *sna,
1605					       const struct drm_mode_fb_cmd *fbcon)
1606{
1607	struct drm_gem_flink flink;
1608	struct kgem_bo *bo;
1609	int ret;
1610
1611	/* Create a new reference for the fbcon so that we can track it
1612	 * using a normal bo and so that when we call gem_close on it we
1613	 * delete our reference and not fbcon's!
1614	 */
1615	VG_CLEAR(flink);
1616	flink.handle = fbcon->handle;
1617	ret = drmIoctl(sna->kgem.fd, DRM_IOCTL_GEM_FLINK, &flink);
1618	if (ret)
1619		return NULL;
1620
1621	bo = kgem_create_for_name(&sna->kgem, flink.name);
1622	if (bo == NULL)
1623		return NULL;
1624
1625	bo->pitch = fbcon->pitch;
1626	return bo;
1627}
1628
1629/* Copy the current framebuffer contents into the front-buffer for a seamless
1630 * transition from e.g. plymouth.
1631 */
1632void sna_copy_fbcon(struct sna *sna)
1633{
1634	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
1635	struct drm_mode_fb_cmd fbcon;
1636	PixmapRec scratch;
1637	struct sna_pixmap *priv;
1638	struct kgem_bo *bo;
1639	BoxRec box;
1640	bool ok;
1641	int sx, sy;
1642	int dx, dy;
1643	int i;
1644
1645	if (wedged(sna))
1646		return;
1647
1648	DBG(("%s\n", __FUNCTION__));
1649	assert((sna->flags & SNA_IS_HOSTED) == 0);
1650
1651	priv = sna_pixmap_move_to_gpu(sna->front, MOVE_WRITE | __MOVE_SCANOUT);
1652	if (priv == NULL)
1653		return;
1654
1655	/* Scan the connectors for a framebuffer and assume that is the fbcon */
1656	VG_CLEAR(fbcon);
1657	fbcon.fb_id = 0;
1658	for (i = 0; i < sna->mode.num_real_crtc; i++) {
1659		struct sna_crtc *crtc = to_sna_crtc(config->crtc[i]);
1660		struct drm_mode_crtc mode;
1661
1662		assert(crtc != NULL);
1663
1664		VG_CLEAR(mode);
1665		mode.crtc_id = crtc->id;
1666		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode))
1667			continue;
1668		if (!mode.fb_id)
1669			continue;
1670
1671		fbcon.fb_id = mode.fb_id;
1672		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETFB, &fbcon)) {
1673			fbcon.fb_id = 0;
1674			continue;
1675		}
1676		break;
1677	}
1678	if (fbcon.fb_id == 0) {
1679		DBG(("%s: no fbcon found\n", __FUNCTION__));
1680		return;
1681	}
1682
1683	if (fbcon.fb_id == fb_id(priv->gpu_bo)) {
1684		DBG(("%s: fb already installed as scanout\n", __FUNCTION__));
1685		return;
1686	}
1687
1688	DBG(("%s: found fbcon, size=%dx%d, depth=%d, bpp=%d\n",
1689	     __FUNCTION__, fbcon.width, fbcon.height, fbcon.depth, fbcon.bpp));
1690
1691	bo = sna_create_bo_for_fbcon(sna, &fbcon);
1692	if (bo == NULL)
1693		return;
1694
1695	DBG(("%s: fbcon handle=%d\n", __FUNCTION__, bo->handle));
1696
1697	scratch.drawable.width = fbcon.width;
1698	scratch.drawable.height = fbcon.height;
1699	scratch.drawable.depth = fbcon.depth;
1700	scratch.drawable.bitsPerPixel = fbcon.bpp;
1701	scratch.devPrivate.ptr = NULL;
1702
1703	box.x1 = box.y1 = 0;
1704	box.x2 = min(fbcon.width, sna->front->drawable.width);
1705	box.y2 = min(fbcon.height, sna->front->drawable.height);
1706
1707	sx = dx = 0;
1708	if (box.x2 < (uint16_t)fbcon.width)
1709		sx = (fbcon.width - box.x2) / 2;
1710	if (box.x2 < sna->front->drawable.width)
1711		dx = (sna->front->drawable.width - box.x2) / 2;
1712
1713	sy = dy = 0;
1714	if (box.y2 < (uint16_t)fbcon.height)
1715		sy = (fbcon.height - box.y2) / 2;
1716	if (box.y2 < sna->front->drawable.height)
1717		dy = (sna->front->drawable.height - box.y2) / 2;
1718
1719	ok = sna->render.copy_boxes(sna, GXcopy,
1720				    &scratch.drawable, bo, sx, sy,
1721				    &sna->front->drawable, priv->gpu_bo, dx, dy,
1722				    &box, 1, 0);
1723	if (!DAMAGE_IS_ALL(priv->gpu_damage))
1724		sna_damage_add_box(&priv->gpu_damage, &box);
1725
1726	kgem_bo_destroy(&sna->kgem, bo);
1727
1728#if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(10, 0)
1729	sna->scrn->pScreen->canDoBGNoneRoot = ok;
1730#endif
1731}
1732
1733static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc)
1734{
1735	RRTransformPtr transform;
1736	PictTransform crtc_to_fb;
1737	struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc;
1738	unsigned pitch_limit;
1739	struct sna_pixmap *priv;
1740	BoxRec b;
1741
1742	assert(sna->scrn->virtualX && sna->scrn->virtualY);
1743
1744	if (sna->flags & SNA_FORCE_SHADOW) {
1745		DBG(("%s: forcing shadow\n", __FUNCTION__));
1746		return true;
1747	}
1748
1749	if (to_sna_crtc(crtc)->fallback_shadow) {
1750		DBG(("%s: fallback shadow\n", __FUNCTION__));
1751		return true;
1752	}
1753
1754	if (sna->flags & SNA_TEAR_FREE && to_sna_crtc(crtc)->slave_pixmap) {
1755		DBG(("%s: TearFree shadow required\n", __FUNCTION__));
1756		return true;
1757	}
1758
1759	if (sna->scrn->virtualX > sna->mode.max_crtc_width ||
1760	    sna->scrn->virtualY > sna->mode.max_crtc_height) {
1761		DBG(("%s: framebuffer too large (%dx%d) > (%dx%d)\n",
1762		    __FUNCTION__,
1763		    sna->scrn->virtualX, sna->scrn->virtualY,
1764		    sna->mode.max_crtc_width, sna->mode.max_crtc_height));
1765		return true;
1766	}
1767
1768	priv = sna_pixmap_force_to_gpu(sna->front, MOVE_READ | __MOVE_SCANOUT);
1769	if (priv == NULL)
1770		return true; /* maybe we can create a bo for the scanout? */
1771
1772	if (sna->kgem.gen == 071)
1773		pitch_limit = priv->gpu_bo->tiling ? 16 * 1024 : 32 * 1024;
1774	else if ((sna->kgem.gen >> 3) > 4)
1775		pitch_limit = 32 * 1024;
1776	else if ((sna->kgem.gen >> 3) == 4)
1777		pitch_limit = priv->gpu_bo->tiling ? 16 * 1024 : 32 * 1024;
1778	else if ((sna->kgem.gen >> 3) == 3)
1779		pitch_limit = priv->gpu_bo->tiling ? 8 * 1024 : 16 * 1024;
1780	else
1781		pitch_limit = 8 * 1024;
1782	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));
1783	if (priv->gpu_bo->pitch > pitch_limit)
1784		return true;
1785
1786	if (priv->gpu_bo->tiling && sna->flags & SNA_LINEAR_FB) {
1787		DBG(("%s: gpu bo is tiled, need linear, forcing shadow\n", __FUNCTION__));
1788		return true;
1789	}
1790
1791	transform = NULL;
1792	if (crtc->transformPresent)
1793		transform = &crtc->transform;
1794	if (RRTransformCompute(crtc->x, crtc->y,
1795			       crtc->mode.HDisplay, crtc->mode.VDisplay,
1796			       crtc->rotation, transform,
1797			       &crtc_to_fb,
1798			       &f_crtc_to_fb,
1799			       &f_fb_to_crtc)) {
1800		bool needs_transform = true;
1801		unsigned rotation = rotation_reduce(&to_sna_crtc(crtc)->primary, crtc->rotation);
1802		DBG(("%s: natively supported rotation? rotation=%x & supported=%x == %d\n",
1803		     __FUNCTION__, crtc->rotation, to_sna_crtc(crtc)->primary.rotation.supported,
1804		     !!(crtc->rotation & to_sna_crtc(crtc)->primary.rotation.supported)));
1805		if (to_sna_crtc(crtc)->primary.rotation.supported & rotation)
1806			needs_transform = RRTransformCompute(crtc->x, crtc->y,
1807							     crtc->mode.HDisplay, crtc->mode.VDisplay,
1808							     RR_Rotate_0, transform,
1809							     NULL, NULL, NULL);
1810		if (needs_transform) {
1811			DBG(("%s: RandR transform present\n", __FUNCTION__));
1812			return true;
1813		}
1814	}
1815
1816	/* And finally check that it is entirely visible */
1817	b.x1 = b.y1 = 0;
1818	b.x2 = crtc->mode.HDisplay;
1819	b.y2 = crtc->mode.VDisplay;
1820	pixman_f_transform_bounds(&f_crtc_to_fb, &b);
1821	DBG(("%s? bounds (%d, %d), (%d, %d), framebufer %dx%d\n",
1822	     __FUNCTION__, b.x1, b.y1, b.x2, b.y2,
1823		 sna->scrn->virtualX, sna->scrn->virtualY));
1824
1825	if  (b.x1 < 0 || b.y1 < 0 ||
1826	     b.x2 > sna->scrn->virtualX ||
1827	     b.y2 > sna->scrn->virtualY) {
1828		DBG(("%s: scanout is partly outside the framebuffer\n",
1829		     __FUNCTION__));
1830		return true;
1831	}
1832
1833	return false;
1834}
1835
1836static void set_shadow(struct sna *sna, RegionPtr region)
1837{
1838	struct sna_pixmap *priv = sna_pixmap(sna->front);
1839
1840	assert(priv->gpu_bo);
1841	assert(sna->mode.shadow);
1842
1843	DBG(("%s: waiting for region %dx[(%d, %d), (%d, %d)], front handle=%d, shadow handle=%d\n",
1844	     __FUNCTION__,
1845	     region_num_rects(region),
1846	     region->extents.x1, region->extents.y1,
1847	     region->extents.x2, region->extents.y2,
1848	     priv->gpu_bo->handle, sna->mode.shadow->handle));
1849
1850	assert(priv->pinned & PIN_SCANOUT);
1851	assert((priv->pinned & PIN_PRIME) == 0);
1852	assert(sna->mode.shadow != priv->gpu_bo);
1853
1854	RegionCopy(&sna->mode.shadow_region, region);
1855
1856	priv->move_to_gpu = wait_for_shadow;
1857	priv->move_to_gpu_data = sna;
1858}
1859
1860static struct kgem_bo *
1861get_scanout_bo(struct sna *sna, PixmapPtr pixmap)
1862{
1863	struct sna_pixmap *priv;
1864
1865	priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | __MOVE_SCANOUT);
1866	if (!priv)
1867		return NULL;
1868
1869	if (priv->gpu_bo->pitch & 63) {
1870		struct kgem_bo *tmp;
1871		BoxRec b;
1872
1873		DBG(("%s: converting to scanout bo due to bad pitch [%d]\n",
1874		     __FUNCTION__, priv->gpu_bo->pitch));
1875
1876		if (priv->pinned) {
1877			DBG(("%s: failed as the Pixmap is already pinned [%x]\n",
1878			     __FUNCTION__, priv->pinned));
1879			return NULL;
1880		}
1881
1882		tmp = kgem_create_2d(&sna->kgem,
1883				     pixmap->drawable.width,
1884				     pixmap->drawable.height,
1885				     sna->scrn->bitsPerPixel,
1886				     priv->gpu_bo->tiling,
1887				     CREATE_EXACT | CREATE_SCANOUT);
1888		if (tmp == NULL) {
1889			DBG(("%s: allocation failed\n", __FUNCTION__));
1890			return NULL;
1891		}
1892
1893		b.x1 = 0;
1894		b.y1 = 0;
1895		b.x2 = pixmap->drawable.width;
1896		b.y2 = pixmap->drawable.height;
1897
1898		if (sna->render.copy_boxes(sna, GXcopy,
1899					   &pixmap->drawable, priv->gpu_bo, 0, 0,
1900					   &pixmap->drawable, tmp, 0, 0,
1901					   &b, 1, COPY_LAST)) {
1902			DBG(("%s: copy failed\n", __FUNCTION__));
1903			kgem_bo_destroy(&sna->kgem, tmp);
1904			return NULL;
1905		}
1906
1907		kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
1908		priv->gpu_bo = tmp;
1909	}
1910
1911	priv->pinned |= PIN_SCANOUT;
1912	return priv->gpu_bo;
1913}
1914
1915static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
1916{
1917	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
1918	ScrnInfoPtr scrn = crtc->scrn;
1919	struct sna *sna = to_sna(scrn);
1920	struct kgem_bo *bo;
1921
1922	sna_crtc->transform = false;
1923	sna_crtc->rotation = RR_Rotate_0;
1924
1925	if (use_shadow(sna, crtc)) {
1926		unsigned long tiled_limit;
1927		int tiling;
1928
1929force_shadow:
1930		if (!sna_crtc_enable_shadow(sna, sna_crtc)) {
1931			DBG(("%s: failed to enable crtc shadow\n", __FUNCTION__));
1932			return NULL;
1933		}
1934
1935		DBG(("%s: attaching to per-crtc pixmap %dx%d\n",
1936		     __FUNCTION__, crtc->mode.HDisplay, crtc->mode.VDisplay));
1937
1938		bo = sna_crtc->shadow_bo;
1939		if (bo) {
1940			if (sna_crtc->shadow_bo_width == crtc->mode.HDisplay &&
1941			    sna_crtc->shadow_bo_height == crtc->mode.VDisplay) {
1942				DBG(("%s: reusing current shadow bo handle=%d\n",
1943				     __FUNCTION__, bo->handle));
1944				goto out_shadow;
1945			}
1946
1947			kgem_bo_destroy(&sna->kgem, bo);
1948			sna_crtc->shadow_bo = NULL;
1949		}
1950
1951		tiling = I915_TILING_X;
1952		if (sna->kgem.gen == 071)
1953			tiled_limit = 16 * 1024 * 8;
1954		else if ((sna->kgem.gen >> 3) > 4)
1955			tiled_limit = 32 * 1024 * 8;
1956		else if ((sna->kgem.gen >> 3) == 4)
1957			tiled_limit = 16 * 1024 * 8;
1958		else
1959			tiled_limit = 8 * 1024 * 8;
1960		if ((unsigned long)crtc->mode.HDisplay * scrn->bitsPerPixel > tiled_limit)
1961			tiling = I915_TILING_NONE;
1962		if (sna->flags & SNA_LINEAR_FB)
1963			tiling = I915_TILING_NONE;
1964
1965		bo = kgem_create_2d(&sna->kgem,
1966				    crtc->mode.HDisplay, crtc->mode.VDisplay,
1967				    scrn->bitsPerPixel,
1968				    tiling, CREATE_SCANOUT);
1969		if (bo == NULL) {
1970			DBG(("%s: failed to allocate crtc scanout\n", __FUNCTION__));
1971			return NULL;
1972		}
1973
1974		if (!get_fb(sna, bo, crtc->mode.HDisplay, crtc->mode.VDisplay)) {
1975			DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
1976			kgem_bo_destroy(&sna->kgem, bo);
1977			return NULL;
1978		}
1979
1980		if (__sna_pixmap_get_bo(sna->front) && !crtc->transformPresent) {
1981			DrawableRec tmp;
1982			BoxRec b;
1983
1984			b.x1 = crtc->x;
1985			b.y1 = crtc->y;
1986			b.x2 = crtc->x + crtc->mode.HDisplay;
1987			b.y2 = crtc->y + crtc->mode.VDisplay;
1988
1989			DBG(("%s: copying onto shadow CRTC: (%d, %d)x(%d, %d), handle=%d\n",
1990			     __FUNCTION__,
1991			     b.x1, b.y1,
1992			     b.x2, b.y2,
1993			     bo->handle));
1994
1995			tmp.width = crtc->mode.HDisplay;
1996			tmp.height = crtc->mode.VDisplay;
1997			tmp.depth = sna->front->drawable.depth;
1998			tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
1999
2000			(void)sna->render.copy_boxes(sna, GXcopy,
2001						     &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0,
2002						     &tmp, bo, -b.x1, -b.y1,
2003						     &b, 1, 0);
2004		}
2005
2006		sna_crtc->shadow_bo_width = crtc->mode.HDisplay;
2007		sna_crtc->shadow_bo_height = crtc->mode.VDisplay;
2008		sna_crtc->shadow_bo = bo;
2009out_shadow:
2010		sna_crtc->transform = true;
2011		return kgem_bo_reference(bo);
2012	} else {
2013		if (sna_crtc->shadow_bo) {
2014			kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo);
2015			sna_crtc->shadow_bo = NULL;
2016		}
2017
2018		if (sna_crtc->slave_pixmap) {
2019			DBG(("%s: attaching to scanout pixmap\n", __FUNCTION__));
2020			bo = get_scanout_bo(sna, sna_crtc->slave_pixmap);
2021			if (bo == NULL) {
2022				DBG(("%s: failed to pin crtc scanout\n", __FUNCTION__));
2023				sna_crtc->fallback_shadow = true;
2024				goto force_shadow;
2025			}
2026
2027			if (!get_fb(sna, bo,
2028				    sna_crtc->slave_pixmap->drawable.width,
2029				    sna_crtc->slave_pixmap->drawable.height)) {
2030				DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
2031				sna_crtc->fallback_shadow = true;
2032				goto force_shadow;
2033			}
2034		} else {
2035			DBG(("%s: attaching to framebuffer\n", __FUNCTION__));
2036			bo = get_scanout_bo(sna, sna->front);
2037			if (bo == NULL) {
2038				DBG(("%s: failed to pin framebuffer\n", __FUNCTION__));
2039				sna_crtc->fallback_shadow = true;
2040				goto force_shadow;
2041			}
2042
2043			if (!get_fb(sna, bo, scrn->virtualX, scrn->virtualY)) {
2044				DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
2045				sna_crtc->fallback_shadow = true;
2046				goto force_shadow;
2047			}
2048		}
2049
2050		if (sna->flags & SNA_TEAR_FREE) {
2051			assert(sna_crtc->slave_pixmap == NULL);
2052
2053			DBG(("%s: enabling TearFree shadow\n", __FUNCTION__));
2054			if (!sna_crtc_enable_shadow(sna, sna_crtc)) {
2055				DBG(("%s: failed to enable crtc shadow\n", __FUNCTION__));
2056				return NULL;
2057			}
2058
2059			if (sna->mode.shadow == NULL && !wedged(sna)) {
2060				RegionRec region;
2061				struct kgem_bo *shadow;
2062
2063				DBG(("%s: creating TearFree shadow bo\n", __FUNCTION__));
2064
2065				region.extents.x1 = 0;
2066				region.extents.y1 = 0;
2067				region.extents.x2 = sna->scrn->virtualX;
2068				region.extents.y2 = sna->scrn->virtualY;
2069				region.data = NULL;
2070
2071				shadow = kgem_create_2d(&sna->kgem,
2072							region.extents.x2,
2073							region.extents.y2,
2074							scrn->bitsPerPixel,
2075							kgem_choose_tiling(&sna->kgem,
2076									   I915_TILING_X,
2077									   region.extents.x2,
2078									   region.extents.y2,
2079									   sna->scrn->bitsPerPixel),
2080							CREATE_SCANOUT);
2081				if (shadow == NULL) {
2082					DBG(("%s: failed to allocate TearFree shadow bo\n", __FUNCTION__));
2083					sna_crtc->fallback_shadow = true;
2084					goto force_shadow;
2085				}
2086
2087				if (!get_fb(sna, shadow,
2088					    region.extents.x2,
2089					    region.extents.y2)) {
2090					DBG(("%s: failed to bind fb for TearFeee shadow\n", __FUNCTION__));
2091					kgem_bo_destroy(&sna->kgem, shadow);
2092					sna_crtc->fallback_shadow = true;
2093					goto force_shadow;
2094				}
2095
2096				sna->mode.shadow = shadow;
2097				set_shadow(sna, &region);
2098			}
2099
2100			sna_crtc_disable_override(sna, sna_crtc);
2101		} else
2102			sna_crtc_disable_shadow(sna, sna_crtc);
2103
2104		sna_crtc->rotation = rotation_reduce(&sna_crtc->primary, crtc->rotation);
2105		assert(sna_crtc->primary.rotation.supported & sna_crtc->rotation);
2106		return kgem_bo_reference(bo);
2107	}
2108}
2109
2110static void sna_crtc_randr(xf86CrtcPtr crtc)
2111{
2112	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
2113	struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc;
2114	PictTransform crtc_to_fb;
2115	PictFilterPtr filter;
2116	xFixed *params;
2117	int nparams;
2118	RRTransformPtr transform;
2119	int needs_transform;
2120
2121	transform = NULL;
2122	if (crtc->transformPresent)
2123		transform = &crtc->transform;
2124
2125	needs_transform =
2126		RRTransformCompute(crtc->x, crtc->y,
2127				   crtc->mode.HDisplay, crtc->mode.VDisplay,
2128				   crtc->rotation, transform,
2129				   &crtc_to_fb,
2130				   &f_crtc_to_fb,
2131				   &f_fb_to_crtc);
2132
2133	filter = NULL;
2134	params = NULL;
2135	nparams = 0;
2136	if (sna_crtc->transform) {
2137#ifdef RANDR_12_INTERFACE
2138		if (transform) {
2139			if (transform->nparams) {
2140				params = malloc(transform->nparams * sizeof(xFixed));
2141				if (params) {
2142					memcpy(params, transform->params,
2143					       transform->nparams * sizeof(xFixed));
2144					nparams = transform->nparams;
2145					filter = transform->filter;
2146				}
2147			} else
2148				filter = transform->filter;
2149		}
2150#endif
2151		crtc->transform_in_use = needs_transform;
2152	} else
2153		crtc->transform_in_use = sna_crtc->rotation != RR_Rotate_0;
2154
2155	crtc->crtc_to_framebuffer = crtc_to_fb;
2156	crtc->f_crtc_to_framebuffer = f_crtc_to_fb;
2157	crtc->f_framebuffer_to_crtc = f_fb_to_crtc;
2158
2159	free(crtc->params);
2160	crtc->params  = params;
2161	crtc->nparams = nparams;
2162
2163	crtc->filter = filter;
2164	if (filter) {
2165		crtc->filter_width  = filter->width;
2166		crtc->filter_height = filter->height;
2167	} else {
2168		crtc->filter_width  = 0;
2169		crtc->filter_height = 0;
2170	}
2171
2172	crtc->bounds.x1 = 0;
2173	crtc->bounds.x2 = crtc->mode.HDisplay;
2174	crtc->bounds.y1 = 0;
2175	crtc->bounds.y2 = crtc->mode.VDisplay;
2176	pixman_f_transform_bounds(&f_crtc_to_fb, &crtc->bounds);
2177
2178	DBG(("%s: transform? %d, bounds (%d, %d), (%d, %d)\n",
2179	     __FUNCTION__, crtc->transform_in_use,
2180	     crtc->bounds.x1, crtc->bounds.y1,
2181	     crtc->bounds.x2, crtc->bounds.y2));
2182}
2183
2184static void
2185sna_crtc_damage(xf86CrtcPtr crtc)
2186{
2187	ScreenPtr screen = crtc->scrn->pScreen;
2188	struct sna *sna = to_sna(crtc->scrn);
2189	RegionRec region, *damage;
2190
2191	region.extents = crtc->bounds;
2192	region.data = NULL;
2193
2194	if (region.extents.x1 < 0)
2195		region.extents.x1 = 0;
2196	if (region.extents.y1 < 0)
2197		region.extents.y1 = 0;
2198	if (region.extents.x2 > screen->width)
2199		region.extents.x2 = screen->width;
2200	if (region.extents.y2 > screen->height)
2201		region.extents.y2 = screen->height;
2202
2203	DBG(("%s: marking crtc %d as completely damaged (%d, %d), (%d, %d)\n",
2204	     __FUNCTION__, to_sna_crtc(crtc)->id,
2205	     region.extents.x1, region.extents.y1,
2206	     region.extents.x2, region.extents.y2));
2207	to_sna_crtc(crtc)->client_damage = region;
2208
2209	assert(sna->mode.shadow_damage && sna->mode.shadow_active);
2210	damage = DamageRegion(sna->mode.shadow_damage);
2211	RegionUnion(damage, damage, &region);
2212
2213	DBG(("%s: damage now %dx[(%d, %d), (%d, %d)]\n",
2214	     __FUNCTION__,
2215	     region_num_rects(damage),
2216	     damage->extents.x1, damage->extents.y1,
2217	     damage->extents.x2, damage->extents.y2));
2218}
2219
2220static char *outputs_for_crtc(xf86CrtcPtr crtc, char *outputs, int max)
2221{
2222	struct sna *sna = to_sna(crtc->scrn);
2223	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
2224	int len, i;
2225
2226	for (i = len = 0; i < sna->mode.num_real_output; i++) {
2227		xf86OutputPtr output = config->output[i];
2228
2229		if (output->crtc != crtc)
2230			continue;
2231
2232		len += snprintf(outputs+len, max-len, "%s, ", output->name);
2233	}
2234	assert(len >= 2);
2235	outputs[len-2] = '\0';
2236
2237	return outputs;
2238}
2239
2240static const char *rotation_to_str(Rotation rotation)
2241{
2242	switch (rotation & RR_Rotate_All) {
2243	case 0:
2244	case RR_Rotate_0: return "normal";
2245	case RR_Rotate_90: return "left";
2246	case RR_Rotate_180: return "inverted";
2247	case RR_Rotate_270: return "right";
2248	default: return "unknown";
2249	}
2250}
2251
2252static const char *reflection_to_str(Rotation rotation)
2253{
2254	switch (rotation & RR_Reflect_All) {
2255	case 0: return "none";
2256	case RR_Reflect_X: return "X axis";
2257	case RR_Reflect_Y: return "Y axis";
2258	case RR_Reflect_X | RR_Reflect_Y: return "X and Y axes";
2259	default: return "invalid";
2260	}
2261}
2262
2263static Bool
2264__sna_crtc_set_mode(xf86CrtcPtr crtc)
2265{
2266	struct sna *sna = to_sna(crtc->scrn);
2267	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
2268	struct kgem_bo *saved_bo, *bo;
2269	uint32_t saved_offset;
2270	bool saved_transform;
2271
2272	DBG(("%s\n", __FUNCTION__));
2273
2274	saved_bo = sna_crtc->bo;
2275	saved_transform = sna_crtc->transform;
2276	saved_offset = sna_crtc->offset;
2277
2278	sna_crtc->fallback_shadow = false;
2279retry: /* Attach per-crtc pixmap or direct */
2280	bo = sna_crtc_attach(crtc);
2281	if (bo == NULL) {
2282		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
2283			   "unable to attach scanout\n");
2284		goto error;
2285	}
2286
2287	/* Prevent recursion when enabling outputs during execbuffer */
2288	if (bo->exec && RQ(bo->rq)->bo == NULL)
2289		_kgem_submit(&sna->kgem);
2290
2291	sna_crtc->bo = bo;
2292	if (!sna_crtc_apply(crtc)) {
2293		int err = errno;
2294
2295		kgem_bo_destroy(&sna->kgem, bo);
2296
2297		if (!sna_crtc->shadow) {
2298			sna_crtc->fallback_shadow = true;
2299			goto retry;
2300		}
2301
2302		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
2303			   "failed to set mode: %s [%d]\n", strerror(err), err);
2304		goto error;
2305	}
2306
2307	bo->active_scanout++;
2308	if (saved_bo) {
2309		assert(saved_bo->active_scanout);
2310		assert(saved_bo->refcnt >= saved_bo->active_scanout);
2311		saved_bo->active_scanout--;
2312		kgem_bo_destroy(&sna->kgem, saved_bo);
2313	}
2314
2315	sna_crtc_randr(crtc);
2316	if (sna_crtc->transform)
2317		sna_crtc_damage(crtc);
2318	sna->mode.front_active += saved_bo == NULL;
2319	sna->mode.dirty = true;
2320	DBG(("%s: front_active=%d\n", __FUNCTION__, sna->mode.front_active));
2321
2322	return TRUE;
2323
2324error:
2325	sna_crtc->offset = saved_offset;
2326	sna_crtc->transform = saved_transform;
2327	sna_crtc->bo = saved_bo;
2328	sna_mode_discover(sna);
2329	return FALSE;
2330}
2331
2332static Bool
2333sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
2334			Rotation rotation, int x, int y)
2335{
2336	struct sna *sna = to_sna(crtc->scrn);
2337	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
2338	struct drm_mode_modeinfo saved_kmode;
2339	char outputs[256];
2340
2341	if (mode->HDisplay == 0 || mode->VDisplay == 0)
2342		return FALSE;
2343
2344	assert(sna_crtc);
2345
2346	xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO,
2347		   "switch to mode %dx%d@%.1f on %s using pipe %d, position (%d, %d), rotation %s, reflection %s\n",
2348		   mode->HDisplay, mode->VDisplay, xf86ModeVRefresh(mode),
2349		   outputs_for_crtc(crtc, outputs, sizeof(outputs)), sna_crtc->pipe,
2350		   x, y, rotation_to_str(rotation), reflection_to_str(rotation));
2351
2352	assert(mode->HDisplay <= sna->mode.max_crtc_width &&
2353	       mode->VDisplay <= sna->mode.max_crtc_height);
2354
2355#if HAS_GAMMA
2356	drmModeCrtcSetGamma(sna->kgem.fd, sna_crtc->id,
2357			    crtc->gamma_size,
2358			    crtc->gamma_red,
2359			    crtc->gamma_green,
2360			    crtc->gamma_blue);
2361#endif
2362
2363	saved_kmode = sna_crtc->kmode;
2364	mode_to_kmode(&sna_crtc->kmode, mode);
2365	if (__sna_crtc_set_mode(crtc))
2366		return TRUE;
2367
2368	sna_crtc->kmode = saved_kmode;
2369	return FALSE;
2370}
2371
2372static void
2373sna_crtc_dpms(xf86CrtcPtr crtc, int mode)
2374{
2375	struct sna_crtc *priv = to_sna_crtc(crtc);
2376
2377	DBG(("%s(pipe %d, dpms mode -> %d):= active=%d\n",
2378	     __FUNCTION__, priv->pipe, mode, mode == DPMSModeOn));
2379	if (priv->dpms_mode == mode)
2380		return;
2381
2382	assert(priv);
2383	priv->dpms_mode = mode;
2384
2385	if (mode == DPMSModeOn && crtc->enabled && priv->bo == NULL) {
2386		if (__sna_crtc_set_mode(crtc))
2387			update_flush_interval(to_sna(crtc->scrn));
2388		else
2389			mode = DPMSModeOff;
2390	}
2391
2392	if (mode != DPMSModeOn)
2393		sna_crtc_disable(crtc);
2394}
2395
2396void sna_mode_adjust_frame(struct sna *sna, int x, int y)
2397{
2398	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
2399	xf86CrtcPtr crtc;
2400	int saved_x, saved_y;
2401
2402	if ((unsigned)config->compat_output >= config->num_output)
2403		return;
2404
2405	crtc = config->output[config->compat_output]->crtc;
2406	if (crtc == NULL || !crtc->enabled)
2407		return;
2408
2409	if (crtc->x == x && crtc->y == y)
2410		return;
2411
2412	saved_x = crtc->x;
2413	saved_y = crtc->y;
2414
2415	crtc->x = x;
2416	crtc->y = y;
2417	if (to_sna_crtc(crtc) && !__sna_crtc_set_mode(crtc)) {
2418		crtc->x = saved_x;
2419		crtc->y = saved_y;
2420	}
2421}
2422
2423static void
2424sna_crtc_gamma_set(xf86CrtcPtr crtc,
2425		       CARD16 *red, CARD16 *green, CARD16 *blue, int size)
2426{
2427	assert(to_sna_crtc(crtc));
2428	drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
2429			    to_sna_crtc(crtc)->id,
2430			    size, red, green, blue);
2431}
2432
2433static void
2434sna_crtc_destroy(xf86CrtcPtr crtc)
2435{
2436	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
2437
2438	if (sna_crtc == NULL)
2439		return;
2440
2441	free(sna_crtc);
2442	crtc->driver_private = NULL;
2443}
2444
2445#if HAS_PIXMAP_SHARING
2446static Bool
2447sna_crtc_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap)
2448{
2449	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
2450
2451	if (sna_crtc == NULL)
2452		return FALSE;
2453
2454	if (pixmap == sna_crtc->slave_pixmap)
2455		return TRUE;
2456
2457	DBG(("%s: CRTC:%d, pipe=%d setting scanout pixmap=%ld\n",
2458	     __FUNCTION__, sna_crtc->id,  sna_crtc->pipe,
2459	     pixmap ? pixmap->drawable.serialNumber : 0));
2460
2461	/* Disable first so that we can unregister the damage tracking */
2462	sna_crtc_disable_shadow(to_sna(crtc->scrn), sna_crtc);
2463
2464	sna_crtc->slave_pixmap = pixmap;
2465
2466	return TRUE;
2467}
2468#endif
2469
2470static const xf86CrtcFuncsRec sna_crtc_funcs = {
2471#if XF86_CRTC_VERSION >= 1
2472	.dpms = sna_crtc_dpms,
2473#endif
2474	.set_mode_major = sna_crtc_set_mode_major,
2475	.gamma_set = sna_crtc_gamma_set,
2476	.destroy = sna_crtc_destroy,
2477#if HAS_PIXMAP_SHARING
2478	.set_scanout_pixmap = sna_crtc_set_scanout_pixmap,
2479#endif
2480};
2481
2482inline static bool prop_is_rotation(struct drm_mode_get_property *prop)
2483{
2484	if ((prop->flags & (1 << 5)) == 0)
2485		return false;
2486
2487	if (strcmp(prop->name, "rotation"))
2488		return false;
2489
2490	return true;
2491}
2492
2493static int plane_details(struct sna *sna, struct plane *p)
2494{
2495	struct local_mode_obj_get_properties arg;
2496	uint64_t stack_props[24];
2497	uint32_t *props = (uint32_t *)stack_props;
2498	uint64_t *values = stack_props + 8;
2499	int i, type = DRM_PLANE_TYPE_OVERLAY;
2500
2501	memset(&arg, 0, sizeof(struct local_mode_obj_get_properties));
2502	arg.obj_id = p->id;
2503	arg.obj_type = LOCAL_MODE_OBJECT_PLANE;
2504
2505	arg.props_ptr = (uintptr_t)props;
2506	arg.prop_values_ptr = (uintptr_t)values;
2507	arg.count_props = 16;
2508
2509	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg))
2510		return -1;
2511
2512	DBG(("%s: object %d (type %x) has %d props\n", __FUNCTION__,
2513	     p->id, LOCAL_MODE_OBJECT_PLANE, arg.count_props));
2514
2515	if (arg.count_props > 16) {
2516		props = malloc(2*sizeof(uint64_t)*arg.count_props);
2517		if (props == NULL)
2518			return -1;
2519
2520		values = (uint64_t *)props + arg.count_props;
2521
2522		arg.props_ptr = (uintptr_t)props;
2523		arg.prop_values_ptr = (uintptr_t)values;
2524
2525		if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg))
2526			arg.count_props = 0;
2527	}
2528	VG(VALGRIND_MAKE_MEM_DEFINED(arg.props_ptr, sizeof(uint32_t)*arg.count_props));
2529	VG(VALGRIND_MAKE_MEM_DEFINED(arg.prop_values_ptr, sizeof(uint64_t)*arg.count_props));
2530
2531	for (i = 0; i < arg.count_props; i++) {
2532		struct drm_mode_get_property prop;
2533
2534		memset(&prop, 0, sizeof(prop));
2535		prop.prop_id = props[i];
2536		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) {
2537			ERR(("%s: prop[%d].id=%d GETPROPERTY failed with errno=%d\n",
2538			     __FUNCTION__, i, props[i], errno));
2539			continue;
2540		}
2541
2542		DBG(("%s: prop[%d] .id=%ld, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i,
2543		     (long)props[i], prop.name, (unsigned)prop.flags, (long)values[i]));
2544
2545		if (strcmp(prop.name, "type") == 0) {
2546			type = values[i];
2547		} else if (prop_is_rotation(&prop)) {
2548			struct drm_mode_property_enum *enums;
2549
2550			p->rotation.prop = props[i];
2551			p->rotation.current = values[i];
2552
2553			DBG(("%s: found rotation property .id=%d, value=%ld, num_enums=%d\n",
2554			     __FUNCTION__, prop.prop_id, (long)values[i], prop.count_enum_blobs));
2555			enums = malloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum));
2556			if (enums != NULL) {
2557				prop.count_values = 0;
2558				prop.enum_blob_ptr = (uintptr_t)enums;
2559
2560				if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop) == 0) {
2561					int j;
2562
2563					/* XXX we assume that the mapping between kernel enum and
2564					 * RandR remains fixed for our lifetimes.
2565					 */
2566					VG(VALGRIND_MAKE_MEM_DEFINED(enums, sizeof(*enums)*prop.count_enum_blobs));
2567					for (j = 0; j < prop.count_enum_blobs; j++) {
2568						DBG(("%s: rotation[%d] = %s [%lx]\n", __FUNCTION__,
2569						     j, enums[j].name, (long)enums[j].value));
2570						p->rotation.supported |= 1 << enums[j].value;
2571					}
2572				}
2573
2574				free(enums);
2575			}
2576		}
2577	}
2578
2579	if (props != (uint32_t *)stack_props)
2580		free(props);
2581
2582	DBG(("%s: plane=%d type=%d\n", __FUNCTION__, p->id, type));
2583	return type;
2584}
2585
2586static void
2587sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc)
2588{
2589#define LOCAL_IOCTL_SET_CAP	DRM_IOWR(0x0d, struct local_set_cap)
2590#define LOCAL_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xb5, struct local_mode_get_plane_res)
2591#define LOCAL_IOCTL_MODE_GETPLANE DRM_IOWR(0xb6, struct local_mode_get_plane)
2592	struct local_set_cap {
2593		uint64_t name;
2594		uint64_t value;
2595	} cap;
2596	struct local_mode_get_plane_res {
2597		uint64_t plane_id_ptr;
2598		uint64_t count_planes;
2599	} r;
2600	uint32_t stack_planes[32];
2601	uint32_t *planes = stack_planes;
2602	int i;
2603
2604	VG_CLEAR(cap);
2605	cap.name = DRM_CLIENT_CAP_UNIVERSAL_PLANES;
2606	cap.value = 1;
2607	(void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_SET_CAP, &cap);
2608
2609	VG_CLEAR(r);
2610	r.plane_id_ptr = (uintptr_t)planes;
2611	r.count_planes = ARRAY_SIZE(stack_planes);
2612	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANERESOURCES, &r)) {
2613		ERR(("%s: GETPLANERESOURCES failed with errno=%d\n", __FUNCTION__, errno));
2614		return;
2615	}
2616
2617	DBG(("%s: %d planes\n", __FUNCTION__, (int)r.count_planes));
2618
2619	if (r.count_planes > ARRAY_SIZE(stack_planes)) {
2620		planes = malloc(sizeof(uint32_t)*r.count_planes);
2621		if (planes == NULL)
2622			return;
2623
2624		r.plane_id_ptr = (uintptr_t)planes;
2625		if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANERESOURCES, &r))
2626			r.count_planes = 0;
2627	}
2628
2629	VG(VALGRIND_MAKE_MEM_DEFINED(planes, sizeof(uint32_t)*r.count_planes));
2630
2631	for (i = 0; i < r.count_planes; i++) {
2632		struct local_mode_get_plane {
2633			uint32_t plane_id;
2634
2635			uint32_t crtc_id;
2636			uint32_t fb_id;
2637
2638			uint32_t possible_crtcs;
2639			uint32_t gamma_size;
2640
2641			uint32_t count_format_types;
2642			uint64_t format_type_ptr;
2643		} p;
2644		struct plane details;
2645
2646		VG_CLEAR(p);
2647		p.plane_id = planes[i];
2648		p.count_format_types = 0;
2649		if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANE, &p))
2650			continue;
2651
2652		if ((p.possible_crtcs & (1 << crtc->pipe)) == 0)
2653			continue;
2654
2655		DBG(("%s: plane %d is attached to our pipe=%d\n",
2656		     __FUNCTION__, planes[i], crtc->pipe));
2657
2658		details.id = p.plane_id;
2659		details.rotation.prop = 0;
2660		details.rotation.supported = RR_Rotate_0;
2661		details.rotation.current = RR_Rotate_0;
2662
2663		switch (plane_details(sna, &details)) {
2664		default:
2665			break;
2666
2667		case DRM_PLANE_TYPE_PRIMARY:
2668			crtc->primary = details;
2669			break;
2670
2671		case DRM_PLANE_TYPE_CURSOR:
2672			break;
2673
2674		case DRM_PLANE_TYPE_OVERLAY:
2675			if (crtc->sprite.id == 0)
2676				crtc->sprite = details;
2677			break;
2678		}
2679	}
2680
2681	if (planes != stack_planes)
2682		free(planes);
2683}
2684
2685static void
2686sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc)
2687{
2688	crtc->rotation = RR_Rotate_0;
2689	crtc->primary.rotation.supported = RR_Rotate_0;
2690	crtc->primary.rotation.current = RR_Rotate_0;
2691	crtc->sprite.rotation = crtc->primary.rotation;
2692}
2693
2694static void
2695sna_crtc_init__cursor(struct sna *sna, struct sna_crtc *crtc)
2696{
2697	struct drm_mode_cursor arg;
2698
2699	VG_CLEAR(arg);
2700	arg.flags = DRM_MODE_CURSOR_BO;
2701	arg.crtc_id = crtc->id;
2702	arg.width = arg.height = 0;
2703	arg.handle = 0;
2704
2705	(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg);
2706}
2707
2708static bool
2709sna_crtc_add(ScrnInfoPtr scrn, int id)
2710{
2711	struct sna *sna = to_sna(scrn);
2712	xf86CrtcPtr crtc;
2713	struct sna_crtc *sna_crtc;
2714	struct drm_i915_get_pipe_from_crtc_id get_pipe;
2715
2716	DBG(("%s(%d)\n", __FUNCTION__, id));
2717
2718	sna_crtc = calloc(sizeof(struct sna_crtc), 1);
2719	if (sna_crtc == NULL)
2720		return false;
2721
2722	sna_crtc->id = id;
2723	sna_crtc->dpms_mode = -1;
2724
2725	VG_CLEAR(get_pipe);
2726	get_pipe.pipe = 0;
2727	get_pipe.crtc_id = sna_crtc->id;
2728	if (drmIoctl(sna->kgem.fd,
2729		     DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID,
2730		     &get_pipe)) {
2731		free(sna_crtc);
2732		return false;
2733	}
2734	sna_crtc->pipe = get_pipe.pipe;
2735
2736	if (is_zaphod(scrn) &&
2737	    scrn->confScreen->device->screen != sna_crtc->pipe) {
2738		free(sna_crtc);
2739		return true;
2740	}
2741
2742	sna_crtc_init__rotation(sna, sna_crtc);
2743
2744	sna_crtc_find_planes(sna, sna_crtc);
2745
2746	DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x, sprite id=%x: supported-rotations=%x, current-rotation=%x\n",
2747	     __FUNCTION__, sna_crtc->id, sna_crtc->pipe,
2748	     sna_crtc->primary.id, sna_crtc->primary.rotation.supported, sna_crtc->primary.rotation.current,
2749	     sna_crtc->sprite.id, sna_crtc->sprite.rotation.supported, sna_crtc->sprite.rotation.current));
2750
2751	list_init(&sna_crtc->shadow_link);
2752
2753	crtc = xf86CrtcCreate(scrn, &sna_crtc_funcs);
2754	if (crtc == NULL) {
2755		free(sna_crtc);
2756		return false;
2757	}
2758
2759	sna_crtc_init__cursor(sna, sna_crtc);
2760
2761	crtc->driver_private = sna_crtc;
2762	sna_crtc->base = crtc;
2763	DBG(("%s: attached crtc[%d] pipe=%d\n",
2764	     __FUNCTION__, id, sna_crtc->pipe));
2765
2766	return true;
2767}
2768
2769static bool
2770is_panel(int type)
2771{
2772#define DRM_MODE_CONNECTOR_LVDS 7
2773#define DRM_MODE_CONNECTOR_eDP 14
2774#define DRM_MODE_CONNECTOR_DSI 16
2775	return (type == DRM_MODE_CONNECTOR_LVDS ||
2776		type == DRM_MODE_CONNECTOR_eDP ||
2777		type == DRM_MODE_CONNECTOR_DSI);
2778}
2779
2780static int
2781find_property(struct sna *sna, struct sna_output *output, const char *name)
2782{
2783	struct drm_mode_get_property prop;
2784	int i;
2785
2786	VG_CLEAR(prop);
2787	for (i = 0; i < output->num_props; i++) {
2788		prop.prop_id = output->prop_ids[i];
2789		prop.count_values = 0;
2790		prop.count_enum_blobs = 0;
2791		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
2792			continue;
2793
2794		if (strcmp(prop.name, name) == 0)
2795			return i;
2796	}
2797
2798	return -1;
2799}
2800
2801static xf86OutputStatus
2802sna_output_detect(xf86OutputPtr output)
2803{
2804	struct sna *sna = to_sna(output->scrn);
2805	struct sna_output *sna_output = output->driver_private;
2806	union compat_mode_get_connector compat_conn;
2807
2808	DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id));
2809
2810	if (!sna_output->id) {
2811		DBG(("%s(%s) hiding due to lost connection\n", __FUNCTION__, output->name));
2812		return XF86OutputStatusDisconnected;
2813	}
2814
2815	VG_CLEAR(compat_conn);
2816	compat_conn.conn.connector_id = sna_output->id;
2817	sna_output->num_modes = compat_conn.conn.count_modes = 0; /* reprobe */
2818	compat_conn.conn.count_encoders = 0;
2819	compat_conn.conn.count_props = sna_output->num_props;
2820	compat_conn.conn.props_ptr = (uintptr_t)sna_output->prop_ids;
2821	compat_conn.conn.prop_values_ptr = (uintptr_t)sna_output->prop_values;
2822
2823	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn))
2824		return XF86OutputStatusUnknown;
2825	DBG(("%s(%s): num modes %d -> %d, num props %d -> %d\n",
2826	     __FUNCTION__, output->name,
2827	     sna_output->num_modes, compat_conn.conn.count_modes,
2828	     sna_output->num_props, compat_conn.conn.count_props));
2829
2830	assert(compat_conn.conn.count_props == sna_output->num_props);
2831
2832	while (compat_conn.conn.count_modes && compat_conn.conn.count_modes != sna_output->num_modes) {
2833		struct drm_mode_modeinfo *new_modes;
2834		int old_count;
2835
2836		old_count = sna_output->num_modes;
2837		new_modes = realloc(sna_output->modes,
2838				    sizeof(*sna_output->modes)*compat_conn.conn.count_modes);
2839		if (new_modes == NULL)
2840			break;
2841
2842		sna_output->modes = new_modes;
2843		sna_output->num_modes = compat_conn.conn.count_modes;
2844		compat_conn.conn.modes_ptr = (uintptr_t)sna_output->modes;
2845		compat_conn.conn.count_encoders = 0;
2846		compat_conn.conn.count_props = 0;
2847		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
2848			sna_output->num_modes = min(old_count, sna_output->num_modes);
2849			break;
2850		}
2851		VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->modes, sizeof(*sna_output->modes)*sna_output->num_modes));
2852	}
2853
2854	DBG(("%s(%s): found %d modes, connection status=%d\n",
2855	     __FUNCTION__, output->name, sna_output->num_modes, compat_conn.conn.connection));
2856
2857	switch (compat_conn.conn.connection) {
2858	case DRM_MODE_CONNECTED:
2859		return XF86OutputStatusConnected;
2860	case DRM_MODE_DISCONNECTED:
2861		return XF86OutputStatusDisconnected;
2862	default:
2863	case DRM_MODE_UNKNOWNCONNECTION:
2864		return XF86OutputStatusUnknown;
2865	}
2866}
2867
2868static Bool
2869sna_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
2870{
2871	struct sna_output *sna_output = output->driver_private;
2872	struct sna *sna = to_sna(output->scrn);
2873
2874	if (mode->HDisplay > sna->mode.max_crtc_width)
2875		return MODE_VIRTUAL_X;
2876	if (mode->VDisplay > sna->mode.max_crtc_height)
2877		return MODE_VIRTUAL_Y;
2878
2879	/* Check that we can successfully pin this into the global GTT */
2880	if ((kgem_can_create_2d(&sna->kgem,
2881				mode->HDisplay, mode->VDisplay,
2882				sna->scrn->bitsPerPixel) & KGEM_CAN_CREATE_GTT) == 0)
2883		return MODE_MEM_VIRT;
2884
2885	/*
2886	 * If the connector type is a panel, we will use the panel limit to
2887	 * verfiy whether the mode is valid.
2888	 */
2889	if (sna_output->has_panel_limits) {
2890		if (mode->HDisplay > sna_output->panel_hdisplay ||
2891		    mode->VDisplay > sna_output->panel_vdisplay)
2892			return MODE_PANEL;
2893	}
2894
2895	return MODE_OK;
2896}
2897
2898static void
2899sna_output_attach_edid(xf86OutputPtr output)
2900{
2901	struct sna *sna = to_sna(output->scrn);
2902	struct sna_output *sna_output = output->driver_private;
2903	struct drm_mode_get_blob blob;
2904	void *old, *raw = NULL;
2905	xf86MonPtr mon = NULL;
2906
2907	if (sna_output->edid_idx == -1)
2908		return;
2909
2910	raw = sna_output->edid_raw;
2911	blob.length = sna_output->edid_len;
2912
2913	if (blob.length && output->MonInfo) {
2914		old = alloca(blob.length);
2915		memcpy(old, raw, blob.length);
2916	} else
2917		old = NULL;
2918
2919	blob.blob_id = sna_output->prop_values[sna_output->edid_idx];
2920	DBG(("%s: attaching EDID id=%d, current=%d\n",
2921	     __FUNCTION__, blob.blob_id, sna_output->edid_blob_id));
2922	if (blob.blob_id == sna_output->edid_blob_id && 0) { /* sigh */
2923		if (output->MonInfo) {
2924			/* XXX the property keeps on disappearing... */
2925			RRChangeOutputProperty(output->randr_output,
2926					       MakeAtom("EDID", strlen("EDID"), TRUE),
2927					       XA_INTEGER, 8, PropModeReplace,
2928					       sna_output->edid_len,
2929					       sna_output->edid_raw,
2930					       FALSE, FALSE);
2931
2932			return;
2933		}
2934
2935		goto skip_read;
2936	}
2937
2938	blob.data = (uintptr_t)raw;
2939	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
2940		goto done;
2941
2942	DBG(("%s: retrieving blob id=%d, length=%d\n",
2943	     __FUNCTION__, blob.blob_id, blob.length));
2944
2945	if (blob.length > sna_output->edid_len) {
2946		raw = realloc(raw, blob.length);
2947		if (raw == NULL)
2948			goto done;
2949
2950		VG(memset(raw, 0, blob.length));
2951		blob.data = (uintptr_t)raw;
2952		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
2953			goto done;
2954	}
2955
2956	if (old &&
2957	    blob.length == sna_output->edid_len &&
2958	    memcmp(old, raw, blob.length) == 0) {
2959		assert(sna_output->edid_raw == raw);
2960		sna_output->edid_blob_id = blob.blob_id;
2961		RRChangeOutputProperty(output->randr_output,
2962				       MakeAtom("EDID", strlen("EDID"), TRUE),
2963				       XA_INTEGER, 8, PropModeReplace,
2964				       sna_output->edid_len,
2965				       sna_output->edid_raw,
2966				       FALSE, FALSE);
2967		return;
2968	}
2969
2970skip_read:
2971	if (raw) {
2972		mon = xf86InterpretEDID(output->scrn->scrnIndex, raw);
2973		if (mon && blob.length > 128)
2974			mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
2975	}
2976
2977done:
2978	xf86OutputSetEDID(output, mon);
2979	if (raw) {
2980		sna_output->edid_raw = raw;
2981		sna_output->edid_len = blob.length;
2982		sna_output->edid_blob_id = blob.blob_id;
2983	}
2984}
2985
2986static DisplayModePtr
2987default_modes(void)
2988{
2989#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,6,99,900,0)
2990	return xf86GetDefaultModes();
2991#else
2992	return xf86GetDefaultModes(0, 0);
2993#endif
2994}
2995
2996static DisplayModePtr
2997sna_output_panel_edid(xf86OutputPtr output, DisplayModePtr modes)
2998{
2999	xf86MonPtr mon = output->MonInfo;
3000	DisplayModePtr i, m, preferred = NULL;
3001	int max_x = 0, max_y = 0;
3002	float max_vrefresh = 0.0;
3003
3004	if (mon && GTF_SUPPORTED(mon->features.msc))
3005		return modes;
3006
3007	for (m = modes; m; m = m->next) {
3008		if (m->type & M_T_PREFERRED)
3009			preferred = m;
3010		max_x = max(max_x, m->HDisplay);
3011		max_y = max(max_y, m->VDisplay);
3012		max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m));
3013	}
3014
3015	max_vrefresh = max(max_vrefresh, 60.0);
3016	max_vrefresh *= (1 + SYNC_TOLERANCE);
3017
3018	m = default_modes();
3019	xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0);
3020
3021	for (i = m; i; i = i->next) {
3022		if (xf86ModeVRefresh(i) > max_vrefresh)
3023			i->status = MODE_VSYNC;
3024		if (preferred &&
3025		    i->HDisplay >= preferred->HDisplay &&
3026		    i->VDisplay >= preferred->VDisplay &&
3027		    xf86ModeVRefresh(i) >= xf86ModeVRefresh(preferred))
3028			i->status = MODE_PANEL;
3029	}
3030
3031	xf86PruneInvalidModes(output->scrn, &m, FALSE);
3032
3033	return xf86ModesAdd(modes, m);
3034}
3035
3036static DisplayModePtr
3037sna_output_get_modes(xf86OutputPtr output)
3038{
3039	struct sna_output *sna_output = output->driver_private;
3040	DisplayModePtr Modes = NULL, current = NULL;
3041	int i;
3042
3043	DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id));
3044	assert(sna_output->id);
3045
3046	sna_output_attach_edid(output);
3047
3048	if (output->crtc) {
3049		struct drm_mode_crtc mode;
3050
3051		VG_CLEAR(mode);
3052		assert(to_sna_crtc(output->crtc));
3053		mode.crtc_id = to_sna_crtc(output->crtc)->id;
3054
3055		if (drmIoctl(to_sna(output->scrn)->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode) == 0) {
3056			DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__,
3057			     to_sna_crtc(output->crtc)->id,
3058			     to_sna_crtc(output->crtc)->pipe,
3059			     mode.mode_valid && mode.mode.clock));
3060
3061			if (mode.mode_valid && mode.mode.clock) {
3062				current = calloc(1, sizeof(DisplayModeRec));
3063				if (current) {
3064					mode_from_kmode(output->scrn, &mode.mode, current);
3065					current->type |= M_T_DRIVER | M_T_PREFERRED;
3066				}
3067			}
3068		}
3069	}
3070
3071	DBG(("%s: adding %d probed modes\n", __FUNCTION__, sna_output->num_modes));
3072
3073	for (i = 0; i < sna_output->num_modes; i++) {
3074		DisplayModePtr mode;
3075
3076		mode = calloc(1, sizeof(DisplayModeRec));
3077		if (mode == NULL)
3078			continue;
3079
3080		mode = mode_from_kmode(output->scrn,
3081				       &sna_output->modes[i],
3082				       mode);
3083		Modes = xf86ModesAdd(Modes, mode);
3084		if (current && xf86ModesEqual(mode, current)) {
3085			free((void*)current->name);
3086			free(current);
3087			current = NULL;
3088		}
3089		if (current && mode->type & M_T_PREFERRED)
3090			current->type &= ~M_T_PREFERRED;
3091	}
3092
3093	if (current)
3094		Modes = xf86ModesAdd(current, Modes);
3095
3096	/*
3097	 * If the connector type is a panel, we will traverse the kernel mode to
3098	 * get the panel limit. And then add all the standard modes to fake
3099	 * the fullscreen experience.
3100	 * If it is incorrect, please fix me.
3101	 */
3102	sna_output->has_panel_limits = false;
3103	if (sna_output->is_panel) {
3104		sna_output->panel_hdisplay = sna_output->panel_vdisplay = 0;
3105		for (i = 0; i < sna_output->num_modes; i++) {
3106			struct drm_mode_modeinfo *m;
3107
3108			m = &sna_output->modes[i];
3109			if (m->hdisplay > sna_output->panel_hdisplay)
3110				sna_output->panel_hdisplay = m->hdisplay;
3111			if (m->vdisplay > sna_output->panel_vdisplay)
3112				sna_output->panel_vdisplay = m->vdisplay;
3113		}
3114		sna_output->has_panel_limits =
3115			sna_output->panel_hdisplay &&
3116			sna_output->panel_vdisplay;
3117	}
3118
3119	if (sna_output->add_default_modes)
3120		Modes = sna_output_panel_edid(output, Modes);
3121
3122	return Modes;
3123}
3124
3125static void
3126sna_output_destroy(xf86OutputPtr output)
3127{
3128	struct sna_output *sna_output = output->driver_private;
3129	int i;
3130
3131	if (sna_output == NULL)
3132		return;
3133
3134	free(sna_output->edid_raw);
3135	for (i = 0; i < sna_output->num_props; i++) {
3136		if (sna_output->props[i].kprop == NULL)
3137			continue;
3138
3139		if (sna_output->props[i].atoms) {
3140			if (output->randr_output)
3141				RRDeleteOutputProperty(output->randr_output, sna_output->props[i].atoms[0]);
3142			free(sna_output->props[i].atoms);
3143		}
3144
3145		drmModeFreeProperty(sna_output->props[i].kprop);
3146	}
3147	free(sna_output->props);
3148	free(sna_output->prop_ids);
3149	free(sna_output->prop_values);
3150
3151	backlight_close(&sna_output->backlight);
3152
3153	free(sna_output);
3154	output->driver_private = NULL;
3155}
3156
3157static void
3158sna_output_dpms(xf86OutputPtr output, int dpms)
3159{
3160	struct sna *sna = to_sna(output->scrn);
3161	struct sna_output *sna_output = output->driver_private;
3162	int old_dpms = sna_output->dpms_mode;
3163
3164	DBG(("%s(%s:%d): dpms=%d (current: %d), active? %d\n",
3165	     __FUNCTION__, output->name, sna_output->id,
3166	     dpms, sna_output->dpms_mode,
3167	     output->crtc != NULL));
3168
3169	if (!sna_output->id)
3170		return;
3171
3172	if (old_dpms == dpms)
3173		return;
3174
3175	/* Record the value of the backlight before turning
3176	 * off the display, and reset if after turning it on.
3177	 * Order is important as the kernel may record and also
3178	 * reset the backlight across DPMS. Hence we need to
3179	 * record the value before the kernel modifies it
3180	 * and reapply it afterwards.
3181	 */
3182	if (sna_output->backlight.iface && dpms != DPMSModeOn) {
3183		if (old_dpms == DPMSModeOn) {
3184			sna_output->backlight_active_level = sna_output_backlight_get(output);
3185			DBG(("%s: saving current backlight %d\n",
3186			     __FUNCTION__, sna_output->backlight_active_level));
3187		}
3188		sna_output->dpms_mode = dpms;
3189		sna_output_backlight_off(sna_output);
3190	}
3191
3192	if (output->crtc &&
3193	    drmModeConnectorSetProperty(sna->kgem.fd,
3194					sna_output->id,
3195					sna_output->dpms_id,
3196					dpms))
3197		dpms = old_dpms;
3198
3199	if (sna_output->backlight.iface && dpms == DPMSModeOn) {
3200		DBG(("%s: restoring previous backlight %d\n",
3201		     __FUNCTION__, sna_output->backlight_active_level));
3202		sna_output_backlight_on(sna_output);
3203	}
3204
3205	sna_output->dpms_mode = dpms;
3206}
3207
3208static bool
3209sna_property_ignore(drmModePropertyPtr prop)
3210{
3211	if (!prop)
3212		return true;
3213
3214	/* ignore blob prop */
3215	if (prop->flags & DRM_MODE_PROP_BLOB)
3216		return true;
3217
3218	/* ignore standard property */
3219	if (!strcmp(prop->name, "EDID") ||
3220	    !strcmp(prop->name, "DPMS"))
3221		return true;
3222
3223	return false;
3224}
3225
3226static void
3227sna_output_create_ranged_atom(xf86OutputPtr output, Atom *atom,
3228			      const char *name, INT32 min, INT32 max,
3229			      uint64_t value, Bool immutable)
3230{
3231	int err;
3232	INT32 atom_range[2];
3233
3234	atom_range[0] = min;
3235	atom_range[1] = max;
3236
3237	*atom = MakeAtom(name, strlen(name), TRUE);
3238
3239	err = RRConfigureOutputProperty(output->randr_output, *atom, FALSE,
3240					TRUE, immutable, 2, atom_range);
3241	if (err != 0)
3242		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
3243			   "RRConfigureOutputProperty error, %d\n", err);
3244
3245	err = RRChangeOutputProperty(output->randr_output, *atom, XA_INTEGER,
3246				     32, PropModeReplace, 1, &value,
3247				     FALSE, FALSE);
3248	if (err != 0)
3249		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
3250			   "RRChangeOutputProperty error, %d\n", err);
3251}
3252
3253static void
3254sna_output_create_resources(xf86OutputPtr output)
3255{
3256	struct sna *sna = to_sna(output->scrn);
3257	struct sna_output *sna_output = output->driver_private;
3258	int i, j, err;
3259
3260	sna_output->props = calloc(sna_output->num_props,
3261				   sizeof(struct sna_property));
3262	if (!sna_output->props)
3263		return;
3264
3265	for (i = 0; i < sna_output->num_props; i++) {
3266		struct sna_property *p = &sna_output->props[i];
3267
3268		p->kprop = drmModeGetProperty(sna->kgem.fd,
3269					      sna_output->prop_ids[i]);
3270		if (sna_property_ignore(p->kprop)) {
3271			drmModeFreeProperty(p->kprop);
3272			p->kprop = NULL;
3273			continue;
3274		}
3275
3276		if (p->kprop->flags & DRM_MODE_PROP_RANGE) {
3277			p->num_atoms = 1;
3278			p->atoms = calloc(p->num_atoms, sizeof(Atom));
3279			if (!p->atoms)
3280				continue;
3281
3282			sna_output_create_ranged_atom(output, &p->atoms[0],
3283						      p->kprop->name,
3284						      p->kprop->values[0],
3285						      p->kprop->values[1],
3286						      sna_output->prop_values[i],
3287						      p->kprop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE);
3288
3289		} else if (p->kprop->flags & DRM_MODE_PROP_ENUM) {
3290			p->num_atoms = p->kprop->count_enums + 1;
3291			p->atoms = calloc(p->num_atoms, sizeof(Atom));
3292			if (!p->atoms)
3293				continue;
3294
3295			p->atoms[0] = MakeAtom(p->kprop->name, strlen(p->kprop->name), TRUE);
3296			for (j = 1; j <= p->kprop->count_enums; j++) {
3297				struct drm_mode_property_enum *e = &p->kprop->enums[j-1];
3298				p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE);
3299			}
3300
3301			err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
3302							FALSE, FALSE,
3303							p->kprop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
3304							p->num_atoms - 1, (INT32 *)&p->atoms[1]);
3305			if (err != 0) {
3306				xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
3307					   "RRConfigureOutputProperty error, %d\n", err);
3308			}
3309
3310			for (j = 0; j < p->kprop->count_enums; j++)
3311				if (p->kprop->enums[j].value == sna_output->prop_values[i])
3312					break;
3313			/* there's always a matching value */
3314			err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
3315						     XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1],
3316						     FALSE, FALSE);
3317			if (err != 0) {
3318				xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
3319					   "RRChangeOutputProperty error, %d\n", err);
3320			}
3321		}
3322	}
3323
3324	if (sna_output->backlight.iface) {
3325		/* Set up the backlight property, which takes effect
3326		 * immediately and accepts values only within the
3327		 * backlight_range.
3328		 */
3329		sna_output_create_ranged_atom(output, &backlight_atom,
3330					      BACKLIGHT_NAME, 0,
3331					      sna_output->backlight.max,
3332					      sna_output->backlight_active_level,
3333					      FALSE);
3334		sna_output_create_ranged_atom(output,
3335					      &backlight_deprecated_atom,
3336					      BACKLIGHT_DEPRECATED_NAME, 0,
3337					      sna_output->backlight.max,
3338					      sna_output->backlight_active_level,
3339					      FALSE);
3340	}
3341}
3342
3343static Bool
3344sna_output_set_property(xf86OutputPtr output, Atom property,
3345			RRPropertyValuePtr value)
3346{
3347	struct sna *sna = to_sna(output->scrn);
3348	struct sna_output *sna_output = output->driver_private;
3349	int i;
3350
3351	if (property == backlight_atom || property == backlight_deprecated_atom) {
3352		INT32 val;
3353		int ret = 0;
3354
3355		if (value->type != XA_INTEGER || value->format != 32 ||
3356		    value->size != 1)
3357		{
3358			return FALSE;
3359		}
3360
3361		val = *(INT32 *)value->data;
3362		DBG(("%s: setting backlight to %d (max=%d)\n",
3363		     __FUNCTION__, (int)val, sna_output->backlight.max));
3364		if (val < 0 || val > sna_output->backlight.max)
3365			return FALSE;
3366
3367		sna_output->backlight_active_level = val;
3368		if (sna_output->dpms_mode == DPMSModeOn)
3369			ret = sna_output_backlight_set(sna_output, val);
3370		return ret == 0;
3371	}
3372
3373	if (!sna_output->id)
3374		return TRUE;
3375
3376	for (i = 0; i < sna_output->num_props; i++) {
3377		struct sna_property *p = &sna_output->props[i];
3378
3379		if (p->atoms == NULL || p->atoms[0] != property)
3380			continue;
3381
3382		if (p->kprop->flags & DRM_MODE_PROP_RANGE) {
3383			uint32_t val;
3384
3385			if (value->type != XA_INTEGER || value->format != 32 ||
3386			    value->size != 1)
3387				return FALSE;
3388			val = *(uint32_t *)value->data;
3389
3390			drmModeConnectorSetProperty(sna->kgem.fd, sna_output->id,
3391						    p->kprop->prop_id, (uint64_t)val);
3392			return TRUE;
3393		} else if (p->kprop->flags & DRM_MODE_PROP_ENUM) {
3394			Atom	atom;
3395			const char	*name;
3396			int		j;
3397
3398			if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
3399				return FALSE;
3400			memcpy(&atom, value->data, 4);
3401			name = NameForAtom(atom);
3402			if (name == NULL)
3403				return FALSE;
3404
3405			/* search for matching name string, then set its value down */
3406			for (j = 0; j < p->kprop->count_enums; j++) {
3407				if (!strcmp(p->kprop->enums[j].name, name)) {
3408					drmModeConnectorSetProperty(sna->kgem.fd, sna_output->id,
3409								    p->kprop->prop_id, p->kprop->enums[j].value);
3410					return TRUE;
3411				}
3412			}
3413			return FALSE;
3414		}
3415	}
3416
3417	/* We didn't recognise this property, just report success in order
3418	 * to allow the set to continue, otherwise we break setting of
3419	 * common properties like EDID.
3420	 */
3421	return TRUE;
3422}
3423
3424static Bool
3425sna_output_get_property(xf86OutputPtr output, Atom property)
3426{
3427	struct sna_output *sna_output = output->driver_private;
3428	int err;
3429
3430	if (property == backlight_atom || property == backlight_deprecated_atom) {
3431		INT32 val;
3432
3433		if (!sna_output->backlight.iface)
3434			return FALSE;
3435
3436		if (sna_output->dpms_mode == DPMSModeOn) {
3437			val = sna_output_backlight_get(output);
3438			if (val < 0)
3439				return FALSE;
3440			DBG(("%s(%s): output on, reporting actual backlight value [%d]\n",
3441			     __FUNCTION__, output->name, val));
3442		} else {
3443			val = sna_output->backlight_active_level;
3444			DBG(("%s(%s): output off, reporting cached backlight value [%d]\n",
3445			     __FUNCTION__, output->name, val));
3446		}
3447
3448		err = RRChangeOutputProperty(output->randr_output, property,
3449					     XA_INTEGER, 32, PropModeReplace, 1, &val,
3450					     FALSE, FALSE);
3451		if (err != 0) {
3452			xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
3453				   "RRChangeOutputProperty error, %d\n", err);
3454			return FALSE;
3455		}
3456
3457		return TRUE;
3458	}
3459
3460	return FALSE;
3461}
3462
3463static const xf86OutputFuncsRec sna_output_funcs = {
3464	.create_resources = sna_output_create_resources,
3465#ifdef RANDR_12_INTERFACE
3466	.set_property = sna_output_set_property,
3467	.get_property = sna_output_get_property,
3468#endif
3469	.dpms = sna_output_dpms,
3470	.detect = sna_output_detect,
3471	.mode_valid = sna_output_mode_valid,
3472
3473	.get_modes = sna_output_get_modes,
3474	.destroy = sna_output_destroy
3475};
3476
3477static const int subpixel_conv_table[] = {
3478	SubPixelUnknown,
3479	SubPixelHorizontalRGB,
3480	SubPixelHorizontalBGR,
3481	SubPixelVerticalRGB,
3482	SubPixelVerticalBGR,
3483	SubPixelNone
3484};
3485
3486static const char * const output_names[] = {
3487	/* DRM_MODE_CONNECTOR_Unknown */	"None",
3488	/* DRM_MODE_CONNECTOR_VGA */		"VGA",
3489	/* DRM_MODE_CONNECTOR_DVII */		"DVI",
3490	/* DRM_MODE_CONNECTOR_DVID */		"DVI",
3491	/* DRM_MODE_CONNECTOR_DVIA */		"DVI",
3492	/* DRM_MODE_CONNECTOR_Composite */	"Composite",
3493	/* DRM_MODE_CONNECTOR_SVIDEO */		"TV",
3494	/* DRM_MODE_CONNECTOR_LVDS */		"LVDS",
3495	/* DRM_MODE_CONNECTOR_Component */	"CTV",
3496	/* DRM_MODE_CONNECTOR_9PinDIN */	"DIN",
3497	/* DRM_MODE_CONNECTOR_DisplayPort */	"DP",
3498	/* DRM_MODE_CONNECTOR_HDMIA */		"HDMI",
3499	/* DRM_MODE_CONNECTOR_HDMIB */		"HDMI",
3500	/* DRM_MODE_CONNECTOR_TV */		"TV",
3501	/* DRM_MODE_CONNECTOR_eDP */		"eDP",
3502	/* DRM_MODE_CONNECTOR_VIRTUAL */	"Virtual",
3503	/* DRM_MODE_CONNECTOR_DSI */		"DSI"
3504};
3505
3506static bool
3507sna_zaphod_match(const char *s, const char *output)
3508{
3509	char t[20];
3510	unsigned int i = 0;
3511
3512	do {
3513		/* match any outputs in a comma list, stopping at whitespace */
3514		switch (*s) {
3515		case '\0':
3516			t[i] = '\0';
3517			return strcmp(t, output) == 0;
3518
3519		case ',':
3520			t[i] ='\0';
3521			if (strcmp(t, output) == 0)
3522				return TRUE;
3523			i = 0;
3524			break;
3525
3526		case ' ':
3527		case '\t':
3528		case '\n':
3529		case '\r':
3530			break;
3531
3532		default:
3533			t[i++] = *s;
3534			break;
3535		}
3536
3537		s++;
3538	} while (i < sizeof(t));
3539
3540	return false;
3541}
3542
3543static bool
3544output_ignored(ScrnInfoPtr scrn, const char *name)
3545{
3546	char monitor_name[64];
3547	const char *monitor;
3548	XF86ConfMonitorPtr conf;
3549
3550	snprintf(monitor_name, sizeof(monitor_name), "monitor-%s", name);
3551	monitor = xf86findOptionValue(scrn->options, monitor_name);
3552	if (!monitor)
3553		monitor = name;
3554
3555	conf = xf86findMonitor(monitor,
3556			       xf86configptr->conf_monitor_lst);
3557	if (conf == NULL && XF86_CRTC_CONFIG_PTR(scrn)->num_output == 0)
3558		conf = xf86findMonitor(scrn->monitor->id,
3559				       xf86configptr->conf_monitor_lst);
3560	if (conf == NULL)
3561		return false;
3562
3563	return xf86CheckBoolOption(conf->mon_option_lst, "Ignore", 0);
3564}
3565
3566static bool
3567gather_encoders(struct sna *sna, uint32_t id, int count,
3568		struct drm_mode_get_encoder *out)
3569{
3570	union compat_mode_get_connector compat_conn;
3571	struct drm_mode_modeinfo dummy;
3572	struct drm_mode_get_encoder enc;
3573	uint32_t *ids = NULL;
3574
3575	VG_CLEAR(compat_conn);
3576	memset(out, 0, sizeof(*out));
3577
3578	do {
3579		free(ids);
3580		ids = malloc(sizeof(*ids) * count);
3581		if (ids == 0)
3582			return false;
3583
3584		compat_conn.conn.connector_id = id;
3585		compat_conn.conn.count_props = 0;
3586		compat_conn.conn.count_modes = 1; /* skip detect */
3587		compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
3588		compat_conn.conn.count_encoders = count;
3589		compat_conn.conn.encoders_ptr = (uintptr_t)ids;
3590
3591		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
3592			DBG(("%s: GETCONNECTOR[%d] failed, ret=%d\n", __FUNCTION__, id, errno));
3593			compat_conn.conn.count_encoders = count = 0;
3594		}
3595
3596		if (count == compat_conn.conn.count_encoders)
3597			break;
3598
3599		count = compat_conn.conn.count_encoders;
3600	} while (1);
3601
3602	for (count = 0; count < compat_conn.conn.count_encoders; count++) {
3603		enc.encoder_id = ids[count];
3604		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
3605			DBG(("%s: GETENCODER[%d] failed, ret=%d\n", __FUNCTION__, ids[count], errno));
3606			count = 0;
3607			break;
3608		}
3609		out->possible_crtcs |= enc.possible_crtcs;
3610		out->possible_clones |= enc.possible_clones;
3611
3612		for (id = 0; id < sna->mode.num_real_encoder; id++) {
3613			if (enc.encoder_id == sna->mode.encoders[id]) {
3614				out->crtc_id |= 1 << id;
3615				break;
3616			}
3617		}
3618	}
3619
3620	free(ids);
3621	return count > 0;
3622}
3623
3624/* We need to map from kms encoder based possible_clones mask to X output based
3625 * possible clones masking. Note that for SDVO and on Haswell with DP/HDMI we
3626 * can have more than one output hanging off the same encoder.
3627 */
3628static void
3629sna_mode_compute_possible_outputs(struct sna *sna)
3630{
3631	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
3632	int encoder_mask[32];
3633	int i, j;
3634
3635	assert(sna->mode.num_real_output < 32);
3636	assert(sna->mode.num_real_crtc < 32);
3637
3638	for (i = 0; i < sna->mode.num_real_output; i++) {
3639		xf86OutputPtr output = config->output[i];
3640		struct sna_output *sna_output = to_sna_output(output);
3641
3642		assert(sna_output);
3643
3644		if (sna_output->id) {
3645			output->possible_clones = sna_output->possible_encoders;
3646			encoder_mask[i] = sna_output->attached_encoders;
3647		} else {
3648			output->possible_clones = 0;
3649			encoder_mask[i] = 0;
3650		}
3651	}
3652
3653	/* Convert from encoder numbering to output numbering */
3654	for (i = 0; i < sna->mode.num_real_output; i++) {
3655		xf86OutputPtr output = config->output[i];
3656		unsigned clones;
3657
3658		if (output->possible_clones == 0)
3659			continue;
3660
3661		clones = 0;
3662		for (j = 0; j < sna->mode.num_real_output; j++)
3663			if (i != j && output->possible_clones & encoder_mask[j])
3664				clones |= 1 << j;
3665		output->possible_clones = clones;
3666
3667		DBG(("%s: updated output '%s' %d [%d] (possible crtc:%x, possible clones:%x)\n",
3668		     __FUNCTION__, output->name, i, to_connector_id(output),
3669		     (uint32_t)output->possible_crtcs,
3670		     (uint32_t)output->possible_clones));
3671	}
3672}
3673
3674static int name_from_path(struct sna *sna,
3675			  struct sna_output *sna_output,
3676			  char *name)
3677{
3678	struct drm_mode_get_blob blob;
3679	char *path;
3680	int id;
3681
3682	id = find_property(sna, sna_output, "PATH");
3683	DBG(("%s: found? PATH=%d\n", __FUNCTION__, id));
3684	if (id == -1)
3685		return 0;
3686
3687	VG_CLEAR(blob);
3688	blob.blob_id = sna_output->prop_values[id];
3689	blob.length = 0;
3690	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
3691		return 0;
3692
3693	do {
3694		id = blob.length;
3695		path = alloca(id + 1);
3696		blob.data = (uintptr_t)path;
3697		VG(memset(path, 0, id));
3698		DBG(("%s: reading %d bytes for path blob\n", __FUNCTION__, id));
3699		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
3700			return 0;
3701	} while (id != blob.length);
3702
3703	path[blob.length] = '\0'; /* paranoia */
3704	DBG(("%s: PATH='%s'\n", __FUNCTION__, path));
3705
3706	/* we only handle MST paths for now */
3707	if (strncmp(path, "mst:", 4) == 0) {
3708		xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
3709		char tmp[5], *c;
3710		int n;
3711
3712		c = strchr(path + 4, '-');
3713		if (c == NULL)
3714			return 0;
3715
3716		id = c - (path + 4);
3717		if (id + 1> 5)
3718			return 0;
3719
3720		memcpy(tmp, path + 4, id);
3721		tmp[id] = '\0';
3722		id = strtoul(tmp, NULL, 0);
3723
3724		for (n = 0; n < sna->mode.num_real_output; n++) {
3725			if (to_sna_output(config->output[n])->id == id)
3726				return snprintf(name, 32, "%s-%s",
3727						config->output[n]->name, c + 1);
3728		}
3729	}
3730
3731	return 0;
3732}
3733
3734static int
3735sna_output_add(struct sna *sna, unsigned id, unsigned serial)
3736{
3737	ScrnInfoPtr scrn = sna->scrn;
3738	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
3739	union compat_mode_get_connector compat_conn;
3740	struct drm_mode_get_encoder enc;
3741	struct drm_mode_modeinfo dummy;
3742	struct sna_output *sna_output;
3743	xf86OutputPtr *outputs, output;
3744	unsigned possible_encoders, attached_encoders, possible_crtcs;
3745	const char *output_name;
3746	char name[32];
3747	int path, len, i;
3748
3749	DBG(("%s(%d): serial=%d\n", __FUNCTION__, id, serial));
3750
3751	COMPILE_TIME_ASSERT(sizeof(struct drm_mode_get_connector) <= sizeof(compat_conn.pad));
3752
3753	VG_CLEAR(compat_conn);
3754	memset(&enc, 0, sizeof(enc));
3755
3756	compat_conn.conn.connector_id = id;
3757	compat_conn.conn.count_props = 0;
3758	compat_conn.conn.count_modes = 1; /* skip detect */
3759	compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
3760	compat_conn.conn.count_encoders = 1;
3761	compat_conn.conn.encoders_ptr = (uintptr_t)&enc.encoder_id;
3762
3763	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
3764		DBG(("%s: GETCONNECTOR[%d] failed, ret=%d\n", __FUNCTION__, id, errno));
3765		return -1;
3766	}
3767	assert(compat_conn.conn.connector_id == id);
3768
3769	if (compat_conn.conn.connector_type < ARRAY_SIZE(output_names))
3770		output_name = output_names[compat_conn.conn.connector_type];
3771	else
3772		output_name = "UNKNOWN";
3773	len = snprintf(name, 32, "%s%d", output_name, compat_conn.conn.connector_type_id);
3774	if (output_ignored(scrn, name))
3775		return 0;
3776
3777	if (enc.encoder_id) {
3778		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
3779			DBG(("%s: GETENCODER[%d] failed, ret=%d\n", __FUNCTION__, enc.encoder_id, errno));
3780			return 0;
3781		}
3782
3783		possible_encoders = enc.possible_clones;
3784		attached_encoders = 0;
3785		for (i = 0; i < sna->mode.num_real_encoder; i++) {
3786			if (enc.encoder_id == sna->mode.encoders[i]) {
3787				attached_encoders = 1 << i;
3788				break;
3789			}
3790		}
3791
3792		if (attached_encoders == 0) {
3793			DBG(("%s: failed to find attached encoder\n", __FUNCTION__));
3794			return 0;
3795		}
3796
3797		possible_crtcs = enc.possible_crtcs;
3798		assert(enc.encoder_id == compat_conn.conn.encoder_id || compat_conn.conn.encoder_id == 0);
3799	} else {
3800		DBG(("%s: unexpected number [%d] of encoders attached\n",
3801		     __FUNCTION__, compat_conn.conn.count_encoders));
3802		if (!gather_encoders(sna, id, compat_conn.conn.count_encoders, &enc)) {
3803			DBG(("%s: gather encoders failed\n", __FUNCTION__));
3804			return 0;
3805		}
3806		possible_encoders = enc.possible_clones;
3807		attached_encoders = enc.crtc_id;
3808		possible_crtcs = enc.possible_crtcs;
3809
3810		memset(&enc, 0, sizeof(enc));
3811		enc.encoder_id = compat_conn.conn.encoder_id;
3812		(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc);
3813	}
3814
3815	if (is_zaphod(scrn)) {
3816		const char *str;
3817
3818		str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD);
3819		if (str && !sna_zaphod_match(str, name)) {
3820			DBG(("%s: zaphod mismatch, want %s, have %s\n", __FUNCTION__, str, name));
3821			return 0;
3822		}
3823
3824		if ((possible_crtcs & (1 << scrn->confScreen->device->screen)) == 0) {
3825			if (str) {
3826				xf86DrvMsg(scrn->scrnIndex, X_ERROR,
3827					   "%s is an invalid output for screen (pipe) %d\n",
3828					   name, scrn->confScreen->device->screen);
3829				return -1;
3830			} else
3831				return 0;
3832		}
3833
3834		possible_crtcs = 1;
3835	}
3836
3837	sna_output = calloc(sizeof(struct sna_output), 1);
3838	if (!sna_output)
3839		return -1;
3840
3841	sna_output->num_props = compat_conn.conn.count_props;
3842	sna_output->prop_ids = malloc(sizeof(uint32_t)*compat_conn.conn.count_props);
3843	sna_output->prop_values = malloc(sizeof(uint64_t)*compat_conn.conn.count_props);
3844
3845	compat_conn.conn.count_encoders = 0;
3846
3847	compat_conn.conn.count_modes = 1;
3848	compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
3849
3850	compat_conn.conn.count_props = sna_output->num_props;
3851	compat_conn.conn.props_ptr = (uintptr_t)sna_output->prop_ids;
3852	compat_conn.conn.prop_values_ptr = (uintptr_t)sna_output->prop_values;
3853
3854	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
3855		DBG(("%s: second! GETCONNECTOR failed, ret=%d\n", __FUNCTION__, errno));
3856		goto cleanup;
3857	}
3858	assert(compat_conn.conn.connector_id == id);
3859
3860	/* statically constructed property list */
3861	assert(sna_output->num_props == compat_conn.conn.count_props);
3862	VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_ids, sizeof(uint32_t)*sna_output->num_props));
3863	VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_values, sizeof(uint64_t)*sna_output->num_props));
3864
3865	/* Construct name from topology, and recheck if output is acceptable */
3866	path = name_from_path(sna, sna_output, name);
3867	if (path) {
3868		const char *str;
3869
3870		if (output_ignored(scrn, name)) {
3871			len = 0;
3872			goto skip;
3873		}
3874
3875		str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD);
3876		if (str && !sna_zaphod_match(str, name)) {
3877			DBG(("%s: zaphod mismatch, want %s, have %s\n", __FUNCTION__, str, name));
3878			len = 0;
3879			goto skip;
3880		}
3881
3882		len = path;
3883	}
3884
3885	/* Check if we are dynamically reattaching an old connector */
3886	if (serial) {
3887		for (i = 0; i < sna->mode.num_real_output; i++) {
3888			output = config->output[i];
3889			if (strcmp(output->name, name) == 0) {
3890				assert(output->scrn == scrn);
3891				assert(output->funcs == &sna_output_funcs);
3892				assert(to_sna_output(output)->id == 0);
3893				sna_output_destroy(output);
3894				goto reset;
3895			}
3896		}
3897	}
3898
3899	output = calloc(1, sizeof(*output) + len + 1);
3900	if (!output)
3901		goto cleanup;
3902
3903	outputs = realloc(config->output, (config->num_output + 1) * sizeof(output));
3904	if (outputs == NULL) {
3905		free(output);
3906		goto cleanup;
3907	}
3908
3909	output->scrn = scrn;
3910	output->funcs = &sna_output_funcs;
3911	output->name = (char *)(output + 1);
3912	memcpy(output->name, name, len + 1);
3913
3914	output->use_screen_monitor = config->num_output != 0;
3915	xf86OutputUseScreenMonitor(output, !output->use_screen_monitor);
3916	assert(output->options);
3917
3918	DBG(("%s: inserting output #%d of %d\n", __FUNCTION__, sna->mode.num_real_output, config->num_output));
3919	for (i = config->num_output; i > sna->mode.num_real_output; i--) {
3920		outputs[i] = outputs[i-1];
3921		assert(outputs[i]->driver_private == NULL);
3922		outputs[i]->possible_clones <<= 1;
3923	}
3924
3925	if (xf86ReturnOptValBool(output->options, OPTION_PRIMARY, FALSE)) {
3926		memmove(outputs + 1, outputs, sizeof(output)*config->num_output);
3927		outputs[0] = output;
3928	} else
3929		outputs[i] = output;
3930	sna->mode.num_real_output++;
3931	config->num_output++;
3932	config->output = outputs;
3933
3934reset:
3935	sna_output->id = compat_conn.conn.connector_id;
3936	sna_output->is_panel = is_panel(compat_conn.conn.connector_type);
3937	sna_output->edid_idx = find_property(sna, sna_output, "EDID");
3938	if (find_property(sna, sna_output, "scaling mode") != -1)
3939		sna_output->add_default_modes =
3940			xf86ReturnOptValBool(output->options, OPTION_DEFAULT_MODES, TRUE);
3941
3942	i = find_property(sna, sna_output, "DPMS");
3943	if (i != -1) {
3944		sna_output->dpms_id = sna_output->prop_ids[i];
3945		sna_output->dpms_mode = sna_output->prop_values[i];
3946		DBG(("%s: found 'DPMS' (idx=%d, id=%d), initial value=%d\n",
3947		     __FUNCTION__, i, sna_output->dpms_id, sna_output->dpms_mode));
3948	} else {
3949		sna_output->dpms_id = -1;
3950		sna_output->dpms_mode = DPMSModeOff;
3951	}
3952
3953	sna_output->possible_encoders = possible_encoders;
3954	sna_output->attached_encoders = attached_encoders;
3955
3956	output->mm_width = compat_conn.conn.mm_width;
3957	output->mm_height = compat_conn.conn.mm_height;
3958
3959	if (compat_conn.conn.subpixel >= ARRAY_SIZE(subpixel_conv_table))
3960		compat_conn.conn.subpixel = 0;
3961	output->subpixel_order = subpixel_conv_table[compat_conn.conn.subpixel];
3962	output->driver_private = sna_output;
3963	sna_output->base = output;
3964
3965	backlight_init(&sna_output->backlight);
3966	if (sna_output->is_panel)
3967		sna_output_backlight_init(output);
3968
3969	output->possible_crtcs = possible_crtcs & count_to_mask(sna->mode.num_real_crtc);
3970	output->interlaceAllowed = TRUE;
3971
3972	if (serial) {
3973		if (output->randr_output == NULL) {
3974			output->randr_output = RROutputCreate(xf86ScrnToScreen(scrn), name, len, output);
3975			if (output->randr_output == NULL)
3976				goto cleanup;
3977		}
3978
3979		sna_output_create_resources(output);
3980		RRPostPendingProperties(output->randr_output);
3981
3982		sna_output->serial = serial;
3983	} else {
3984		/* stash the active CRTC id for our probe function */
3985		if (compat_conn.conn.connection != DRM_MODE_DISCONNECTED)
3986			output->crtc = (void *)(uintptr_t)enc.crtc_id;
3987	}
3988
3989	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",
3990	     __FUNCTION__, name, id, enc.encoder_id,
3991	     (uint32_t)output->possible_crtcs,
3992	     sna_output->attached_encoders,
3993	     sna_output->possible_encoders,
3994	     serial, sna_output->edid_idx, sna_output->dpms_id,
3995	     (unsigned long)(uintptr_t)output->crtc));
3996	assert(sna_output->id == id);
3997
3998	xf86DrvMsg(scrn->scrnIndex, X_INFO,
3999		   "Enabled output %s\n",
4000		   output->name);
4001	return 1;
4002
4003cleanup:
4004	len = -1;
4005skip:
4006	free(sna_output->prop_ids);
4007	free(sna_output->prop_values);
4008	free(sna_output);
4009	return len;
4010}
4011
4012static void sna_output_del(xf86OutputPtr output)
4013{
4014	ScrnInfoPtr scrn = output->scrn;
4015	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
4016	int i;
4017
4018	DBG(("%s(%s)\n", __FUNCTION__, output->name));
4019	assert(to_sna_output(output));
4020
4021	RROutputDestroy(output->randr_output);
4022	sna_output_destroy(output);
4023
4024	while (output->probed_modes)
4025		xf86DeleteMode(&output->probed_modes, output->probed_modes);
4026
4027	free(output);
4028
4029	for (i = 0; i < config->num_output; i++)
4030		if (config->output[i] == output)
4031			break;
4032	assert(i < to_sna(scrn)->mode.num_real_output);
4033	DBG(("%s: removing output #%d of %d\n",
4034	     __FUNCTION__, i, to_sna(scrn)->mode.num_real_output));
4035
4036	for (; i < config->num_output; i++) {
4037		config->output[i] = config->output[i+1];
4038		config->output[i]->possible_clones >>= 1;
4039	}
4040	config->num_output--;
4041	to_sna(scrn)->mode.num_real_output--;
4042}
4043
4044static int output_rank(const void *A, const void *B)
4045{
4046	const xf86OutputPtr *a = A;
4047	const xf86OutputPtr *b = B;
4048	struct sna_output *sa = to_sna_output(*a);
4049	struct sna_output *sb = to_sna_output(*b);
4050
4051	if (sa->is_panel != sb->is_panel)
4052		return sb->is_panel - sa->is_panel;
4053
4054	return strcmp((*a)->name, (*b)->name);
4055}
4056
4057static void sort_config_outputs(struct sna *sna)
4058{
4059	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
4060	qsort(config->output, sna->mode.num_real_output, sizeof(*config->output), output_rank);
4061	sna_mode_compute_possible_outputs(sna);
4062}
4063
4064static void sort_randr_outputs(struct sna *sna, ScreenPtr screen)
4065{
4066	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
4067	rrScrPriv(screen);
4068	int i;
4069
4070	assert(pScrPriv->numOutputs == config->num_output);
4071	for (i = 0; i < config->num_output; i++) {
4072		assert(config->output[i]->randr_output);
4073		pScrPriv->outputs[i] = config->output[i]->randr_output;
4074	}
4075}
4076
4077static bool disable_unused_crtc(struct sna *sna)
4078{
4079	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
4080	bool update = false;
4081	int o, c;
4082
4083	for (c = 0; c < sna->mode.num_real_crtc; c++) {
4084		xf86CrtcPtr crtc = config->crtc[c];
4085
4086		if (!crtc->enabled)
4087			continue;
4088
4089		for (o = 0; o < sna->mode.num_real_output; o++) {
4090			xf86OutputPtr output = config->output[o];
4091			if (output->crtc == crtc)
4092				break;
4093		}
4094
4095		if (o == sna->mode.num_real_output) {
4096			DBG(("%s: CRTC:%d was enabled with no outputs\n",
4097			     __FUNCTION__, to_sna_crtc(crtc)->id));
4098			crtc->enabled = false;
4099			update = true;
4100		}
4101	}
4102
4103	if (update) {
4104		DBG(("%s: disabling unused functions\n", __FUNCTION__));
4105		xf86DisableUnusedFunctions(sna->scrn);
4106	}
4107
4108	return update;
4109}
4110
4111void sna_mode_discover(struct sna *sna)
4112{
4113	ScreenPtr screen = xf86ScrnToScreen(sna->scrn);
4114	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
4115	struct drm_mode_card_res res;
4116	uint32_t connectors[32];
4117	unsigned changed = 0;
4118	unsigned serial;
4119	int i, j;
4120
4121	DBG(("%s()\n", __FUNCTION__));
4122	VG_CLEAR(connectors);
4123
4124	memset(&res, 0, sizeof(res));
4125	res.count_connectors = 32;
4126	res.connector_id_ptr = (uintptr_t)connectors;
4127
4128	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
4129		return;
4130
4131	DBG(("%s: now %d (was %d) connectors\n", __FUNCTION__,
4132	     res.count_connectors, sna->mode.num_real_output));
4133	if (res.count_connectors > 32)
4134		return;
4135
4136	assert(sna->mode.num_real_crtc == res.count_crtcs || is_zaphod(sna->scrn));
4137	assert(sna->mode.max_crtc_width  == res.max_width);
4138	assert(sna->mode.max_crtc_height == res.max_height);
4139	assert(sna->mode.num_real_encoder == res.count_encoders);
4140
4141	serial = ++sna->mode.serial;
4142	if (serial == 0)
4143		serial = ++sna->mode.serial;
4144
4145	for (i = 0; i < res.count_connectors; i++) {
4146		DBG(("%s: connector[%d] = %d\n", __FUNCTION__, i, connectors[i]));
4147		for (j = 0; j < sna->mode.num_real_output; j++) {
4148			xf86OutputPtr output = config->output[j];
4149			if (to_sna_output(output)->id == connectors[i]) {
4150				DBG(("%s: found %s (id=%d)\n", __FUNCTION__, output->name, connectors[i]));
4151				assert(to_sna_output(output)->id);
4152				to_sna_output(output)->serial = serial;
4153				break;
4154			}
4155		}
4156		if (j == sna->mode.num_real_output) {
4157			DBG(("%s: adding id=%d\n", __FUNCTION__, connectors[i]));
4158			changed |= sna_output_add(sna, connectors[i], serial) > 0;
4159		}
4160	}
4161
4162	for (i = 0; i < sna->mode.num_real_output; i++) {
4163		xf86OutputPtr output = config->output[i];
4164
4165		if (to_sna_output(output)->id == 0)
4166			continue;
4167
4168		if (to_sna_output(output)->serial == serial)
4169			continue;
4170
4171		DBG(("%s: removing output %s (id=%d), serial=%u [now %u]\n",
4172		     __FUNCTION__, output->name, to_sna_output(output)->id,
4173		    to_sna_output(output)->serial, serial));
4174
4175		xf86DrvMsg(sna->scrn->scrnIndex, X_INFO,
4176			   "%s output %s\n",
4177			   sna->flags & SNA_REMOVE_OUTPUTS ? "Removed" : "Disabled",
4178			   output->name);
4179		if (sna->flags & SNA_REMOVE_OUTPUTS) {
4180			sna_output_del(output);
4181			i--;
4182		} else {
4183			to_sna_output(output)->id = 0;
4184			output->crtc = NULL;
4185		}
4186		changed |= 2;
4187	}
4188
4189	if (changed) {
4190		DBG(("%s: outputs changed, broadcasting\n", __FUNCTION__));
4191
4192		sna_mode_set_primary(sna);
4193
4194		/* Reorder user visible listing */
4195		sort_config_outputs(sna);
4196		sort_randr_outputs(sna, screen);
4197
4198		if (changed & 2)
4199			disable_unused_crtc(sna);
4200
4201		xf86RandR12TellChanged(screen);
4202	}
4203}
4204
4205static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
4206{
4207	struct sna_pixmap *old_priv, *new_priv;
4208
4209	DBG(("%s\n", __FUNCTION__));
4210
4211	if (wedged(sna))
4212		return;
4213
4214	old_priv = sna_pixmap_force_to_gpu(old, MOVE_READ);
4215	if (!old_priv)
4216		return;
4217
4218	new_priv = sna_pixmap_force_to_gpu(new, MOVE_WRITE | __MOVE_SCANOUT);
4219	if (!new_priv)
4220		return;
4221
4222	if (old_priv->clear) {
4223		(void)sna->render.fill_one(sna, new, new_priv->gpu_bo,
4224					   old_priv->clear_color,
4225					   0, 0,
4226					   new->drawable.width,
4227					   new->drawable.height,
4228					   GXcopy);
4229		new_priv->clear = true;
4230		new_priv->clear_color = old_priv->clear_color;
4231	} else {
4232		BoxRec box;
4233		int16_t sx, sy, dx, dy;
4234
4235		if (new->drawable.width >= old->drawable.width &&
4236		    new->drawable.height >= old->drawable.height)
4237		{
4238			int nx = (new->drawable.width + old->drawable.width - 1) / old->drawable.width;
4239			int ny = (new->drawable.height + old->drawable.height - 1) / old->drawable.height;
4240
4241			box.x1 = box.y1 = 0;
4242
4243			dy = 0;
4244			for (sy = 0; sy < ny; sy++) {
4245				box.y2 = old->drawable.height;
4246				if (box.y2 + dy > new->drawable.height)
4247					box.y2 = new->drawable.height - dy;
4248
4249				dx = 0;
4250				for (sx = 0; sx < nx; sx++) {
4251					box.x2 = old->drawable.width;
4252					if (box.x2 + dx > new->drawable.width)
4253						box.x2 = new->drawable.width - dx;
4254
4255					(void)sna->render.copy_boxes(sna, GXcopy,
4256								     &old->drawable, old_priv->gpu_bo, 0, 0,
4257								     &new->drawable, new_priv->gpu_bo, dx, dy,
4258								     &box, 1, 0);
4259					dx += old->drawable.width;
4260				}
4261				dy += old->drawable.height;
4262			}
4263		} else {
4264			box.x1 = box.y1 = 0;
4265			box.x2 = min(old->drawable.width, new->drawable.width);
4266			box.y2 = min(old->drawable.height, new->drawable.height);
4267
4268			sx = dx = 0;
4269			if (box.x2 < old->drawable.width)
4270				sx = (old->drawable.width - box.x2) / 2;
4271			if (box.x2 < new->drawable.width)
4272				dx = (new->drawable.width - box.x2) / 2;
4273
4274			sy = dy = 0;
4275			if (box.y2 < old->drawable.height)
4276				sy = (old->drawable.height - box.y2) / 2;
4277			if (box.y2 < new->drawable.height)
4278				dy = (new->drawable.height - box.y2) / 2;
4279
4280			DBG(("%s: copying box (%dx%d) from (%d, %d) to (%d, %d)\n",
4281			     __FUNCTION__, box.x2, box.y2, sx, sy, dx, dy));
4282
4283			if (box.x2 != new->drawable.width || box.y2 != new->drawable.height) {
4284				(void)sna->render.fill_one(sna, new, new_priv->gpu_bo, 0,
4285							   0, 0,
4286							   new->drawable.width,
4287							   new->drawable.height,
4288							   GXclear);
4289			}
4290			(void)sna->render.copy_boxes(sna, GXcopy,
4291						     &old->drawable, old_priv->gpu_bo, sx, sy,
4292						     &new->drawable, new_priv->gpu_bo, dx, dy,
4293						     &box, 1, 0);
4294		}
4295	}
4296
4297	sna_damage_all(&new_priv->gpu_damage, new);
4298}
4299
4300static Bool
4301sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
4302{
4303	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
4304	struct sna *sna = to_sna(scrn);
4305	ScreenPtr screen = scrn->pScreen;
4306	PixmapPtr new_front;
4307	int i;
4308
4309	DBG(("%s (%d, %d) -> (%d, %d)\n", __FUNCTION__,
4310	     scrn->virtualX, scrn->virtualY,
4311	     width, height));
4312	assert((sna->flags & SNA_IS_HOSTED) == 0);
4313
4314	if (scrn->virtualX == width && scrn->virtualY == height)
4315		return TRUE;
4316
4317	/* Paranoid defense against rogue internal calls by Xorg */
4318	if (width == 0 || height == 0)
4319		return FALSE;
4320
4321	assert(sna->front);
4322	assert(screen->GetScreenPixmap(screen) == sna->front);
4323
4324	DBG(("%s: creating new framebuffer %dx%d\n",
4325	     __FUNCTION__, width, height));
4326
4327	new_front = screen->CreatePixmap(screen,
4328					 width, height, scrn->depth,
4329					 SNA_CREATE_FB);
4330	if (!new_front)
4331		return FALSE;
4332
4333	xf86DrvMsg(scrn->scrnIndex, X_INFO,
4334		   "resizing framebuffer to %dx%d\n",
4335		   width, height);
4336
4337	for (i = 0; i < sna->mode.num_real_crtc; i++)
4338		sna_crtc_disable_shadow(sna, to_sna_crtc(config->crtc[i]));
4339	assert(sna->mode.shadow_active == 0);
4340	assert(sna->mode.shadow_damage == NULL);
4341	assert(sna->mode.shadow == NULL);
4342
4343	copy_front(sna, sna->front, new_front);
4344
4345	screen->SetScreenPixmap(new_front);
4346	assert(screen->GetScreenPixmap(screen) == new_front);
4347	assert(sna->front == new_front);
4348	screen->DestroyPixmap(new_front); /* owned by screen now */
4349
4350	scrn->virtualX = width;
4351	scrn->virtualY = height;
4352	scrn->displayWidth = width;
4353
4354	/* Flush pending shadow updates */
4355	if (sna->mode.flip_active) {
4356		DBG(("%s: waiting for %d outstanding TearFree flips\n",
4357		     __FUNCTION__, sna->mode.flip_active));
4358		while (sna->mode.flip_active && sna_mode_wait_for_event(sna))
4359			sna_mode_wakeup(sna);
4360	}
4361
4362	/* Only update the CRTCs if we are in control */
4363	if (!scrn->vtSema)
4364		return TRUE;
4365
4366	for (i = 0; i < sna->mode.num_real_crtc; i++) {
4367		xf86CrtcPtr crtc = config->crtc[i];
4368
4369		assert(to_sna_crtc(crtc) != NULL);
4370		if (to_sna_crtc(crtc)->bo == NULL)
4371			continue;
4372
4373		if (!__sna_crtc_set_mode(crtc))
4374			sna_crtc_disable(crtc);
4375	}
4376
4377	sna_mode_wakeup(sna);
4378	kgem_clean_scanout_cache(&sna->kgem);
4379
4380	return TRUE;
4381}
4382
4383/* cursor handling */
4384struct sna_cursor {
4385	struct sna_cursor *next;
4386	uint32_t *image;
4387	Rotation rotation;
4388	int ref;
4389	int size;
4390	int last_width;
4391	int last_height;
4392	unsigned handle;
4393	unsigned serial;
4394	unsigned alloc;
4395};
4396
4397static void
4398rotate_coord(Rotation rotation, int size,
4399	     int x_dst, int y_dst,
4400	     int *x_src, int *y_src)
4401{
4402	int t;
4403
4404	switch (rotation & 0xf) {
4405	case RR_Rotate_0:
4406		break;
4407	case RR_Rotate_90:
4408		t = x_dst;
4409		x_dst = size - y_dst - 1;
4410		y_dst = t;
4411		break;
4412	case RR_Rotate_180:
4413		x_dst = size - x_dst - 1;
4414		y_dst = size - y_dst - 1;
4415		break;
4416	case RR_Rotate_270:
4417		t = x_dst;
4418		x_dst = y_dst;
4419		y_dst = size - t - 1;
4420		break;
4421	}
4422
4423	if (rotation & RR_Reflect_X)
4424		x_dst = size - x_dst - 1;
4425	if (rotation & RR_Reflect_Y)
4426		y_dst = size - y_dst - 1;
4427
4428	*x_src = x_dst;
4429	*y_src = y_dst;
4430}
4431
4432static void
4433rotate_coord_back(Rotation rotation, int size, int *x, int *y)
4434{
4435	int t;
4436
4437	if (rotation & RR_Reflect_X)
4438		*x = size - *x - 1;
4439	if (rotation & RR_Reflect_Y)
4440		*y = size - *y - 1;
4441
4442	switch (rotation & 0xf) {
4443	case RR_Rotate_0:
4444		break;
4445	case RR_Rotate_90:
4446		t = *x;
4447		*x = *y;
4448		*y = size - t - 1;
4449		break;
4450	case RR_Rotate_180:
4451		*x = size - *x - 1;
4452		*y = size - *y - 1;
4453		break;
4454	case RR_Rotate_270:
4455		t = *x;
4456		*x = size - *y - 1;
4457		*y = t;
4458		break;
4459	}
4460}
4461
4462static struct sna_cursor *__sna_create_cursor(struct sna *sna, int size)
4463{
4464	struct sna_cursor *c;
4465
4466	for (c = sna->cursor.cursors; c; c = c->next) {
4467		if (c->ref == 0 && c->alloc >= size) {
4468			__DBG(("%s: stealing handle=%d, serial=%d, rotation=%d, alloc=%d\n",
4469			       __FUNCTION__, c->handle, c->serial, c->rotation, c->alloc));
4470			return c;
4471		}
4472	}
4473
4474	__DBG(("%s(size=%d, num_stash=%d)\n", __FUNCTION__, size, sna->cursor.num_stash));
4475
4476	c = sna->cursor.stash;
4477	assert(c);
4478
4479	c->alloc = ALIGN(size, 4096);
4480	c->handle = gem_create(sna->kgem.fd, c->alloc);
4481	if (c->handle == 0)
4482		return NULL;
4483
4484	/* Old hardware uses physical addresses, which the kernel
4485	 * implements in an incoherent fashion requiring a pwrite.
4486	 */
4487	if (sna->cursor.use_gtt) {
4488		c->image = gem_mmap(sna->kgem.fd, c->handle, c->alloc);
4489		if (c->image == NULL) {
4490			gem_close(sna->kgem.fd, c->handle);
4491			return NULL;
4492		}
4493	} else
4494		c->image = NULL;
4495
4496	__DBG(("%s: handle=%d, allocated %d\n", __FUNCTION__, c->handle, size));
4497
4498	c->ref = 0;
4499	c->serial = 0;
4500	c->rotation = 0;
4501	c->last_width = c->last_height = 0; /* all clear */
4502	c->size = size;
4503
4504	sna->cursor.num_stash--;
4505	sna->cursor.stash = c->next;
4506
4507	c->next = sna->cursor.cursors;
4508	sna->cursor.cursors = c;
4509
4510	return c;
4511}
4512
4513static uint32_t *get_cursor_argb(CursorPtr c)
4514{
4515#ifdef ARGB_CURSOR
4516	return (uint32_t *)c->bits->argb;
4517#else
4518	return NULL;
4519#endif
4520}
4521
4522static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
4523{
4524	struct sna_cursor *cursor;
4525	const uint8_t *source, *mask;
4526	const uint32_t *argb;
4527	uint32_t *image;
4528	int width, height, pitch, size, x, y;
4529	Rotation rotation;
4530
4531	assert(sna->cursor.ref);
4532
4533	cursor = to_sna_crtc(crtc)->cursor;
4534	__DBG(("%s: current cursor handle=%d, serial=%d [expected %d]\n",
4535	       __FUNCTION__,
4536	       cursor ? cursor->handle : 0,
4537	       cursor ? cursor->serial : 0,
4538	       sna->cursor.serial));
4539	if (cursor && cursor->serial == sna->cursor.serial) {
4540		assert(cursor->size == sna->cursor.size);
4541		assert(cursor->rotation == crtc->transform_in_use ? crtc->rotation : RR_Rotate_0);
4542		assert(cursor->ref);
4543		return cursor;
4544	}
4545
4546	__DBG(("%s: cursor=%dx%d, pitch=%d, serial=%d, argb?=%d\n", __FUNCTION__,
4547	       sna->cursor.ref->bits->width,
4548	       sna->cursor.ref->bits->height,
4549	       get_cursor_argb(sna->cursor.ref) ? 4*sna->cursor.ref->bits->width : BitmapBytePad(sna->cursor.ref->bits->width),
4550	       sna->cursor.serial,
4551	       get_cursor_argb(sna->cursor.ref) != NULL));
4552
4553	rotation = crtc->transform_in_use ? crtc->rotation : RR_Rotate_0;
4554
4555	if (sna->cursor.use_gtt) { /* Don't allow phys cursor sharing */
4556		for (cursor = sna->cursor.cursors; cursor; cursor = cursor->next) {
4557			if (cursor->serial == sna->cursor.serial && cursor->rotation == rotation) {
4558				__DBG(("%s: reusing handle=%d, serial=%d, rotation=%d, size=%d\n",
4559				       __FUNCTION__, cursor->handle, cursor->serial, cursor->rotation, cursor->size));
4560				assert(cursor->size == sna->cursor.size);
4561				return cursor;
4562			}
4563		}
4564
4565		cursor = to_sna_crtc(crtc)->cursor;
4566	}
4567
4568	size = sna->cursor.size;
4569	if (cursor && cursor->alloc < 4*size*size)
4570		cursor = NULL;
4571
4572	if (cursor == NULL) {
4573		cursor = __sna_create_cursor(sna, 4*size*size);
4574		if (cursor == NULL) {
4575			DBG(("%s: failed to allocate cursor\n", __FUNCTION__));
4576			return NULL;
4577		}
4578	}
4579
4580	width = sna->cursor.ref->bits->width;
4581	height = sna->cursor.ref->bits->height;
4582	source = sna->cursor.ref->bits->source;
4583	mask = sna->cursor.ref->bits->mask;
4584	argb = get_cursor_argb(sna->cursor.ref);
4585	pitch = BitmapBytePad(width);
4586
4587	image = cursor->image;
4588	if (image == NULL) {
4589		image = sna->cursor.scratch;
4590		cursor->last_width = cursor->last_height = size;
4591	}
4592	if (size > cursor->size ||
4593	    width < cursor->last_width ||
4594	    height < cursor->last_height ||
4595	    rotation != cursor->rotation)
4596		memset(image, 0, 4*size*size);
4597	if (rotation == RR_Rotate_0) {
4598		if (argb == NULL) {
4599			for (y = 0; y < height; y++) {
4600				uint32_t *p = image + y*size;
4601				for (x = 0; x < width; x++) {
4602					int byte = x / 8;
4603					uint8_t bit = 1 << (x & 7);
4604					uint32_t pixel;
4605
4606					if (mask[byte] & bit) {
4607						if (source[byte] & bit)
4608							pixel = sna->cursor.fg;
4609						else
4610							pixel = sna->cursor.bg;
4611					} else
4612						pixel = 0;
4613
4614					*p++ = pixel;
4615				}
4616				mask += pitch;
4617				source += pitch;
4618			}
4619		} else
4620			memcpy_blt(argb, image, 32,
4621				   width * 4, size * 4,
4622				   0, 0,
4623				   0, 0,
4624				   width, height);
4625	} else {
4626		for (y = 0; y < size; y++)
4627			for (x = 0; x < size; x++) {
4628				uint32_t pixel;
4629				int xin, yin;
4630
4631				rotate_coord(rotation, size, x, y, &xin, &yin);
4632				if (xin < width && yin < height)
4633					if (argb == NULL) {
4634						int byte = xin / 8;
4635						int bit = xin & 7;
4636						if (mask[yin*pitch + byte] & (1 << bit)) {
4637							if (source[yin*pitch + byte] & (1 << bit))
4638								pixel = sna->cursor.fg;
4639							else
4640								pixel = sna->cursor.bg;
4641						} else
4642							pixel = 0;
4643					} else
4644						pixel = argb[yin * width + xin];
4645				else
4646					pixel = 0;
4647				image[y * size + x] = pixel;
4648			}
4649	}
4650
4651	if (image != cursor->image) {
4652		struct drm_i915_gem_pwrite pwrite;
4653
4654		VG_CLEAR(pwrite);
4655		pwrite.handle = cursor->handle;
4656		pwrite.offset = 0;
4657		pwrite.size = 4*size*size;
4658		pwrite.data_ptr = (uintptr_t)image;
4659		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite))
4660			__DBG(("%s: cursor update (pwrite) failed: %d\n", __FUNCTION__, errno));
4661	}
4662
4663	cursor->size = size;
4664	cursor->rotation = rotation;
4665	cursor->serial = sna->cursor.serial;
4666	cursor->last_width = width;
4667	cursor->last_height = height;
4668	return cursor;
4669}
4670
4671static unsigned char *
4672sna_realize_cursor(xf86CursorInfoPtr info, CursorPtr cursor)
4673{
4674	return NULL;
4675}
4676
4677/* XXXMRG OsBlockSIGIO() is gone gone, old one remains before porting */
4678#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0) && 0
4679static inline int sigio_block(void)
4680{
4681	OsBlockSIGIO();
4682	return 0;
4683}
4684static inline void sigio_unblock(int was_blocked)
4685{
4686	OsReleaseSIGIO();
4687	(void)was_blocked;
4688}
4689#else
4690#include <xf86_OSproc.h>
4691static inline int sigio_block(void)
4692{
4693	return xf86BlockSIGIO();
4694}
4695static inline void sigio_unblock(int was_blocked)
4696{
4697	xf86UnblockSIGIO(was_blocked);
4698}
4699#endif
4700
4701static void
4702sna_show_cursors(ScrnInfoPtr scrn)
4703{
4704	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
4705	struct sna *sna = to_sna(scrn);
4706	int sigio, c;
4707
4708	DBG(("%s: cursor?=%d\n", __FUNCTION__, sna->cursor.ref != NULL));
4709	if (sna->cursor.ref == NULL)
4710		return;
4711
4712	sigio = sigio_block();
4713	for (c = 0; c < sna->mode.num_real_crtc; c++) {
4714		xf86CrtcPtr crtc = xf86_config->crtc[c];
4715		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
4716		struct drm_mode_cursor arg;
4717		struct sna_cursor *cursor;
4718
4719		assert(sna_crtc != NULL);
4720		if (sna_crtc->bo == NULL)
4721			continue;
4722
4723		if (!crtc->cursor_in_range) {
4724			DBG(("%s: skipping cursor outside CRTC (pipe=%d)\n",
4725			     __FUNCTION__, sna_crtc->pipe));
4726			continue;
4727		}
4728
4729		cursor = __sna_get_cursor(sna, crtc);
4730		if (cursor == NULL ||
4731		    (sna_crtc->cursor == cursor && sna_crtc->last_cursor_size == cursor->size)) {
4732			DBG(("%s: skipping cursor already show on CRTC (pipe=%d)\n",
4733			     __FUNCTION__, sna_crtc->pipe));
4734			continue;
4735		}
4736
4737		DBG(("%s: CRTC pipe=%d, handle->%d\n", __FUNCTION__,
4738		     sna_crtc->pipe, cursor->handle));
4739
4740		VG_CLEAR(arg);
4741		arg.flags = DRM_MODE_CURSOR_BO;
4742		arg.crtc_id = sna_crtc->id;
4743		arg.width = arg.height = cursor->size;
4744		arg.handle = cursor->handle;
4745
4746		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg) == 0) {
4747			if (sna_crtc->cursor) {
4748				assert(sna_crtc->cursor->ref > 0);
4749				sna_crtc->cursor->ref--;
4750			}
4751			cursor->ref++;
4752			sna_crtc->cursor = cursor;
4753			sna_crtc->last_cursor_size = cursor->size;
4754		}
4755	}
4756	sigio_unblock(sigio);
4757	sna->cursor.active = true;
4758}
4759
4760static void
4761sna_set_cursor_colors(ScrnInfoPtr scrn, int _bg, int _fg)
4762{
4763	struct sna *sna = to_sna(scrn);
4764	uint32_t fg = _fg, bg = _bg;
4765
4766	__DBG(("%s(bg=%08x, fg=%08x)\n", __FUNCTION__, bg, fg));
4767
4768	/* Save ARGB versions of these colors */
4769	fg |= 0xff000000;
4770	bg |= 0xff000000;
4771	if (fg == sna->cursor.fg && bg == sna->cursor.bg)
4772		return;
4773
4774	sna->cursor.fg = fg;
4775	sna->cursor.bg = bg;
4776
4777	if (sna->cursor.ref == NULL)
4778		return;
4779
4780	if (get_cursor_argb(sna->cursor.ref))
4781		return;
4782
4783	sna->cursor.serial++;
4784	__DBG(("%s: serial->%d\n", __FUNCTION__, sna->cursor.serial));
4785
4786	sna_show_cursors(scrn);
4787}
4788
4789static void
4790sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc)
4791{
4792	struct drm_mode_cursor arg;
4793
4794	if (!crtc->cursor)
4795		return;
4796
4797	DBG(("%s: CRTC:%d, handle=%d\n", __FUNCTION__, crtc->id, crtc->cursor->handle));
4798	assert(crtc->cursor->ref);
4799
4800	VG_CLEAR(arg);
4801	arg.flags = DRM_MODE_CURSOR_BO;
4802	arg.crtc_id = crtc->id;
4803	arg.width = arg.height = 0;
4804	arg.handle = 0;
4805
4806	(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg);
4807	assert(crtc->cursor->ref > 0);
4808	crtc->cursor->ref--;
4809	crtc->cursor = NULL;
4810	crtc->last_cursor_size = 0;
4811}
4812
4813static void
4814sna_hide_cursors(ScrnInfoPtr scrn)
4815{
4816	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
4817	struct sna *sna = to_sna(scrn);
4818	struct sna_cursor *cursor, **prev;
4819	int sigio, c;
4820
4821	DBG(("%s\n", __FUNCTION__));
4822	sna->cursor.active = false;
4823
4824	sigio = sigio_block();
4825	for (c = 0; c < sna->mode.num_real_crtc; c++) {
4826		assert(to_sna_crtc(xf86_config->crtc[c]));
4827		sna_crtc_disable_cursor(sna, to_sna_crtc(xf86_config->crtc[c]));
4828	}
4829
4830	for (prev = &sna->cursor.cursors; (cursor = *prev) != NULL; ) {
4831		assert(cursor->ref == 0);
4832
4833		if (cursor->serial == sna->cursor.serial) {
4834			prev = &cursor->next;
4835			continue;
4836		}
4837
4838		*prev = cursor->next;
4839		if (cursor->image)
4840			munmap(cursor->image, cursor->alloc);
4841		gem_close(sna->kgem.fd, cursor->handle);
4842
4843		cursor->next = sna->cursor.stash;
4844		sna->cursor.stash = cursor;
4845		sna->cursor.num_stash++;
4846	}
4847
4848	sigio_unblock(sigio);
4849}
4850
4851static void
4852sna_set_cursor_position(ScrnInfoPtr scrn, int x, int y)
4853{
4854	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
4855	struct sna *sna = to_sna(scrn);
4856	int sigio, c;
4857
4858	__DBG(("%s(%d, %d), cursor? %d\n", __FUNCTION__,
4859	       x, y, sna->cursor.ref!=NULL));
4860	if (sna->cursor.ref == NULL)
4861		return;
4862
4863	sigio = sigio_block();
4864	sna->cursor.last_x = x;
4865	sna->cursor.last_y = y;
4866
4867	/* undo what xf86HWCurs did to the coordinates */
4868	x += scrn->frameX0;
4869	y += scrn->frameY0;
4870	for (c = 0; c < sna->mode.num_real_crtc; c++) {
4871		xf86CrtcPtr crtc = xf86_config->crtc[c];
4872		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
4873		struct sna_cursor *cursor = NULL;
4874		struct drm_mode_cursor arg;
4875
4876		assert(sna_crtc != NULL);
4877
4878		VG_CLEAR(arg);
4879		arg.flags = 0;
4880		arg.crtc_id = sna_crtc->id;
4881		arg.handle = 0;
4882
4883		if (sna_crtc->bo == NULL)
4884			goto disable;
4885
4886		if (crtc->transform_in_use) {
4887			int xhot = sna->cursor.ref->bits->xhot;
4888			int yhot = sna->cursor.ref->bits->yhot;
4889			struct pict_f_vector v;
4890
4891			v.v[0] = (x + xhot) + 0.5;
4892			v.v[1] = (y + yhot) + 0.5;
4893			v.v[2] = 1;
4894			pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &v);
4895
4896			rotate_coord_back(crtc->rotation, sna->cursor.size, &xhot, &yhot);
4897
4898			/* cursor will have 0.5 added to it already so floor is sufficent */
4899			arg.x = floor(v.v[0]) - xhot;
4900			arg.y = floor(v.v[1]) - yhot;
4901		} else {
4902			arg.x = x - crtc->x;
4903			arg.y = y - crtc->y;
4904		}
4905
4906		if (arg.x < crtc->mode.HDisplay && arg.x > -sna->cursor.size &&
4907		    arg.y < crtc->mode.VDisplay && arg.y > -sna->cursor.size) {
4908			cursor = __sna_get_cursor(sna, crtc);
4909			if (cursor == NULL)
4910				cursor = sna_crtc->cursor;
4911			if (cursor == NULL) {
4912				__DBG(("%s: failed to grab cursor, disabling\n",
4913				       __FUNCTION__));
4914				goto disable;
4915			}
4916
4917			if (sna_crtc->cursor != cursor || sna_crtc->last_cursor_size != cursor->size) {
4918				arg.flags |= DRM_MODE_CURSOR_BO;
4919				arg.handle = cursor->handle;
4920			}
4921
4922			arg.width = arg.height = cursor->size;
4923			arg.flags |= DRM_MODE_CURSOR_MOVE;
4924			crtc->cursor_in_range = true;
4925		} else {
4926			crtc->cursor_in_range = false;
4927disable:
4928			if (sna_crtc->cursor) {
4929				arg.flags = DRM_MODE_CURSOR_BO;
4930				arg.width = arg.height = 0;
4931			}
4932			cursor = NULL;
4933		}
4934
4935		__DBG(("%s: CRTC:%d (%d, %d), handle=%d, flags=%x (old cursor handle=%d), move? %d, update handle? %d\n",
4936		       __FUNCTION__, sna_crtc->id, arg.x, arg.y, arg.handle, arg.flags, sna_crtc->cursor ? sna_crtc->cursor->handle : 0,
4937		       arg.flags & DRM_MODE_CURSOR_MOVE, arg.flags & DRM_MODE_CURSOR_BO));
4938
4939		if (arg.flags &&
4940		    drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg) == 0) {
4941			if (arg.flags & DRM_MODE_CURSOR_BO) {
4942				if (sna_crtc->cursor) {
4943					assert(sna_crtc->cursor->ref > 0);
4944					sna_crtc->cursor->ref--;
4945				}
4946				sna_crtc->cursor = cursor;
4947				if (cursor) {
4948					sna_crtc->last_cursor_size = cursor->size;
4949					cursor->ref++;
4950				} else
4951					sna_crtc->last_cursor_size = 0;
4952			}
4953		}
4954	}
4955	sigio_unblock(sigio);
4956}
4957
4958#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,2)
4959static Bool
4960sna_load_cursor_argb2(ScrnInfoPtr scrn, CursorPtr cursor)
4961{
4962	return TRUE;
4963}
4964
4965static Bool
4966sna_load_cursor_image2(ScrnInfoPtr scrn, unsigned char *src)
4967{
4968	return TRUE;
4969}
4970#endif
4971
4972static void
4973sna_load_cursor_argb(ScrnInfoPtr scrn, CursorPtr cursor)
4974{
4975}
4976
4977static void
4978sna_load_cursor_image(ScrnInfoPtr scrn, unsigned char *src)
4979{
4980}
4981
4982static int __cursor_size(CursorPtr cursor)
4983{
4984	int i, size;
4985
4986	i = MAX(cursor->bits->width, cursor->bits->height);
4987	for (size = 64; size < i; size <<= 1)
4988		;
4989
4990	return size;
4991}
4992
4993static bool
4994sna_cursor_preallocate(struct sna *sna)
4995{
4996	while (sna->cursor.num_stash < 0) {
4997		struct sna_cursor *cursor = malloc(sizeof(*cursor));
4998		if (!cursor)
4999			return false;
5000
5001		cursor->next = sna->cursor.stash;
5002		sna->cursor.stash = cursor;
5003
5004		sna->cursor.num_stash++;
5005	}
5006
5007	return true;
5008}
5009
5010static Bool
5011sna_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
5012{
5013	struct sna *sna = to_sna_from_screen(screen);
5014
5015	DBG(("%s (%dx%d)?\n", __FUNCTION__,
5016	     cursor->bits->width, cursor->bits->height));
5017
5018	/* cursors are invariant */
5019	if (cursor == sna->cursor.ref)
5020		return TRUE;
5021
5022	if (sna->cursor.ref) {
5023		FreeCursor(sna->cursor.ref, None);
5024		sna->cursor.ref = NULL;
5025	}
5026
5027	sna->cursor.size = __cursor_size(cursor);
5028	if (sna->cursor.size > sna->cursor.max_size)
5029		return FALSE;
5030
5031	if (!sna_cursor_preallocate(sna))
5032		return FALSE;
5033
5034	sna->cursor.ref = cursor;
5035	cursor->refcnt++;
5036	sna->cursor.serial++;
5037
5038	DBG(("%s(%dx%d): ARGB?=%d, serial->%d, size->%d\n", __FUNCTION__,
5039	       cursor->bits->width,
5040	       cursor->bits->height,
5041	       get_cursor_argb(cursor) != NULL,
5042	       sna->cursor.serial,
5043	       sna->cursor.size));
5044	return TRUE;
5045}
5046
5047static void
5048sna_cursor_pre_init(struct sna *sna)
5049{
5050	struct local_get_cap {
5051		uint64_t name;
5052		uint64_t value;
5053	} cap;
5054	int v;
5055
5056	if (sna->mode.num_real_crtc == 0)
5057		return;
5058
5059#define LOCAL_IOCTL_GET_CAP	DRM_IOWR(0x0c, struct local_get_cap)
5060#define DRM_CAP_CURSOR_WIDTH	0x8
5061#define DRM_CAP_CURSOR_HEIGHT	0x9
5062
5063#define I915_PARAM_HAS_COHERENT_PHYS_GTT 29
5064
5065	sna->cursor.max_size = 64;
5066
5067	cap.value = 0;
5068	cap.name = DRM_CAP_CURSOR_WIDTH;
5069	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0)
5070		sna->cursor.max_size = cap.value;
5071
5072	cap.name = DRM_CAP_CURSOR_HEIGHT;
5073	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0 &&
5074	    cap.value < sna->cursor.max_size)
5075		sna->cursor.max_size = cap.value;
5076
5077	v = -1; /* No param uses the sign bit, reserve it for errors */
5078	if (sna->kgem.gen >= 033) {
5079		v = 1;
5080	} else {
5081		drm_i915_getparam_t gp = {
5082			I915_PARAM_HAS_COHERENT_PHYS_GTT,
5083			&v,
5084		};
5085		(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GETPARAM, &gp);
5086	}
5087	sna->cursor.use_gtt = v > 0;
5088	DBG(("%s: cursor updates use_gtt?=%d\n",
5089	     __FUNCTION__, sna->cursor.use_gtt));
5090
5091	if (!sna->cursor.use_gtt) {
5092		sna->cursor.scratch = malloc(sna->cursor.max_size * sna->cursor.max_size * 4);
5093		if (!sna->cursor.scratch)
5094			sna->cursor.max_size = 0;
5095	}
5096
5097	sna->cursor.num_stash = -sna->mode.num_real_crtc;
5098
5099	xf86DrvMsg(sna->scrn->scrnIndex, X_PROBED,
5100		   "Using a maximum size of %dx%d for hardware cursors\n",
5101		   sna->cursor.max_size, sna->cursor.max_size);
5102}
5103
5104static void
5105sna_cursor_close(struct sna *sna)
5106{
5107	sna->cursor.serial = 0;
5108	sna_hide_cursors(sna->scrn);
5109
5110	while (sna->cursor.stash) {
5111		struct sna_cursor *cursor = sna->cursor.stash;
5112		sna->cursor.stash = cursor->next;
5113		free(cursor);
5114	}
5115
5116	sna->cursor.num_stash = -sna->mode.num_real_crtc;
5117}
5118
5119bool
5120sna_cursors_init(ScreenPtr screen, struct sna *sna)
5121{
5122	xf86CursorInfoPtr cursor_info;
5123
5124	if (sna->cursor.max_size == 0)
5125		return false;
5126
5127	cursor_info = xf86CreateCursorInfoRec();
5128	if (cursor_info == NULL)
5129		return false;
5130
5131	cursor_info->MaxWidth = sna->cursor.max_size;
5132	cursor_info->MaxHeight = sna->cursor.max_size;
5133	cursor_info->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
5134			      HARDWARE_CURSOR_UPDATE_UNHIDDEN |
5135			      HARDWARE_CURSOR_ARGB);
5136
5137	cursor_info->RealizeCursor = sna_realize_cursor;
5138	cursor_info->SetCursorColors = sna_set_cursor_colors;
5139	cursor_info->SetCursorPosition = sna_set_cursor_position;
5140	cursor_info->LoadCursorImage = sna_load_cursor_image;
5141	cursor_info->HideCursor = sna_hide_cursors;
5142	cursor_info->ShowCursor = sna_show_cursors;
5143	cursor_info->UseHWCursor = sna_use_hw_cursor;
5144#ifdef ARGB_CURSOR
5145	cursor_info->UseHWCursorARGB = sna_use_hw_cursor;
5146	cursor_info->LoadCursorARGB = sna_load_cursor_argb;
5147#endif
5148#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,3)
5149	cursor_info->LoadCursorImageCheck = sna_load_cursor_image2;
5150#ifdef ARGB_CURSOR
5151	cursor_info->LoadCursorARGBCheck = sna_load_cursor_argb2;
5152#endif
5153#endif
5154
5155	if (!xf86InitCursor(screen, cursor_info)) {
5156		xf86DestroyCursorInfoRec(cursor_info);
5157		return false;
5158	}
5159
5160	sna->cursor.info = cursor_info;
5161	return true;
5162}
5163
5164static void
5165sna_cursors_reload(struct sna *sna)
5166{
5167	DBG(("%s: active?=%d\n", __FUNCTION__, sna->cursor.active));
5168	if (sna->cursor.active)
5169		sna_set_cursor_position(sna->scrn,
5170					sna->cursor.last_x,
5171					sna->cursor.last_y);
5172}
5173
5174static void
5175sna_cursors_fini(struct sna *sna)
5176{
5177	if (sna->cursor.info) {
5178		xf86DestroyCursorInfoRec(sna->cursor.info);
5179		sna->cursor.info = NULL;
5180	}
5181
5182	if (sna->cursor.ref) {
5183		FreeCursor(sna->cursor.ref, None);
5184		sna->cursor.ref = NULL;
5185	}
5186}
5187
5188static bool
5189sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x, int y)
5190{
5191	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5192	struct drm_mode_crtc arg;
5193	uint32_t output_ids[32];
5194	int output_count = 0;
5195	int i;
5196
5197	DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, crtc->id, crtc->pipe, bo->handle));
5198
5199	assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids));
5200	assert(crtc->bo);
5201	assert(crtc->kmode.clock);
5202
5203	for (i = 0; i < sna->mode.num_real_output; i++) {
5204		xf86OutputPtr output = config->output[i];
5205
5206		if (output->crtc != crtc->base)
5207			continue;
5208
5209		DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n",
5210		     __FUNCTION__, output->name, i, to_connector_id(output),
5211		     crtc->id, crtc->pipe,
5212		     (uint32_t)output->possible_crtcs,
5213		     (uint32_t)output->possible_clones));
5214
5215		assert(output->possible_crtcs & (1 << crtc->pipe) ||
5216		       is_zaphod(sna->scrn));
5217
5218		output_ids[output_count] = to_connector_id(output);
5219		if (++output_count == ARRAY_SIZE(output_ids))
5220			return false;
5221	}
5222	assert(output_count);
5223
5224	VG_CLEAR(arg);
5225	arg.crtc_id = crtc->id;
5226	arg.fb_id = fb_id(bo);
5227	assert(arg.fb_id);
5228	arg.x = x;
5229	arg.y = y;
5230	arg.set_connectors_ptr = (uintptr_t)output_ids;
5231	arg.count_connectors = output_count;
5232	arg.mode = crtc->kmode;
5233	arg.mode_valid = 1;
5234
5235	DBG(("%s: applying crtc [%d, pipe=%d] mode=%dx%d+%d+%d@%d, fb=%d across %d outputs [%d...]\n",
5236	     __FUNCTION__, crtc->id, crtc->pipe,
5237	     arg.mode.hdisplay,
5238	     arg.mode.vdisplay,
5239	     arg.x, arg.y,
5240	     arg.mode.clock,
5241	     arg.fb_id,
5242	     output_count, output_count ? output_ids[0] : 0));
5243
5244	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg))
5245		return false;
5246
5247	crtc->offset = y << 16 | x;
5248	return true;
5249}
5250
5251int
5252sna_page_flip(struct sna *sna,
5253	      struct kgem_bo *bo,
5254	      sna_flip_handler_t handler,
5255	      void *data)
5256{
5257	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5258	const int width = sna->scrn->virtualX;
5259	const int height = sna->scrn->virtualY;
5260	int count = 0;
5261	int i;
5262
5263	DBG(("%s: handle %d attached\n", __FUNCTION__, bo->handle));
5264	assert(bo->refcnt);
5265
5266	assert((sna->flags & SNA_IS_HOSTED) == 0);
5267	assert((sna->flags & SNA_TEAR_FREE) == 0);
5268	assert(sna->mode.flip_active == 0);
5269	assert(sna->mode.front_active);
5270	assert(sna->scrn->vtSema);
5271
5272	if ((sna->flags & (data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP)) == 0)
5273		return 0;
5274
5275	kgem_bo_submit(&sna->kgem, bo);
5276
5277	for (i = 0; i < sna->mode.num_real_crtc; i++) {
5278		struct sna_crtc *crtc = config->crtc[i]->driver_private;
5279		struct drm_mode_crtc_page_flip arg;
5280		uint32_t crtc_offset;
5281
5282		DBG(("%s: crtc %d id=%d, pipe=%d active? %d\n",
5283		     __FUNCTION__, i, crtc->id, crtc->pipe, crtc->bo != NULL));
5284		if (crtc->bo == NULL)
5285			continue;
5286		assert(!crtc->transform);
5287		assert(!crtc->slave_pixmap);
5288		assert(crtc->bo->active_scanout);
5289		assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
5290		assert(crtc->flip_bo == NULL);
5291
5292		arg.crtc_id = crtc->id;
5293		arg.fb_id = get_fb(sna, bo, width, height);
5294		if (arg.fb_id == 0) {
5295			assert(count == 0);
5296			return 0;
5297		}
5298
5299		crtc_offset = crtc->base->y << 16 | crtc->base->x;
5300
5301		if (bo->pitch != crtc->bo->pitch || crtc_offset != crtc->offset) {
5302			DBG(("%s: changing pitch (%d == %d) or offset (%x == %x)\n",
5303			     __FUNCTION__,
5304			     bo->pitch, crtc->bo->pitch,
5305			     crtc_offset, crtc->offset));
5306fixup_flip:
5307			if (crtc->bo != bo && sna_crtc_flip(sna, crtc, bo, crtc->base->x, crtc->base->y)) {
5308				assert(crtc->bo->active_scanout);
5309				assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
5310				crtc->bo->active_scanout--;
5311				kgem_bo_destroy(&sna->kgem, crtc->bo);
5312
5313				if (crtc->shadow_bo) {
5314					kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
5315					crtc->shadow_bo = NULL;
5316				}
5317
5318				crtc->bo = kgem_bo_reference(bo);
5319				crtc->bo->active_scanout++;
5320
5321				if (data == NULL)
5322					goto next_crtc;
5323
5324				/* queue a flip in order to send the event */
5325			} else {
5326				if (count && !xf86SetDesiredModes(sna->scrn)) {
5327					xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
5328						   "failed to restore display configuration\n");
5329					for (; i < sna->mode.num_real_crtc; i++)
5330						sna_crtc_disable(config->crtc[i]);
5331				}
5332				return 0;
5333			}
5334		}
5335
5336		/* Only the reference crtc will finally deliver its page flip
5337		 * completion event. All other crtc's events will be discarded.
5338		 */
5339		if (data) {
5340			arg.user_data = (uintptr_t)crtc;
5341			arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
5342		} else {
5343			arg.user_data = 0;
5344			arg.flags = DRM_MODE_PAGE_FLIP_ASYNC;
5345		}
5346		arg.reserved = 0;
5347
5348retry_flip:
5349		DBG(("%s: crtc %d id=%d, pipe=%d  --> fb %d\n",
5350		     __FUNCTION__, i, crtc->id, crtc->pipe, arg.fb_id));
5351		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
5352			ERR(("%s: pageflip failed with err=%d\n", __FUNCTION__, errno));
5353
5354			if (errno == EBUSY) {
5355				struct drm_mode_crtc mode;
5356
5357				memset(&mode, 0, sizeof(mode));
5358				mode.crtc_id = crtc->id;
5359				drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode);
5360
5361				DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=%d\n",
5362				     __FUNCTION__,
5363				     mode.crtc_id, mode.mode_valid,
5364				     mode.fb_id, fb_id(crtc->bo)));
5365
5366				if (mode.fb_id != fb_id(crtc->bo))
5367					goto fixup_flip;
5368
5369				if (count == 0)
5370					return 0;
5371
5372				DBG(("%s: throttling on busy flip / waiting for kernel to catch up\n", __FUNCTION__));
5373				drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_THROTTLE, 0);
5374				sna->kgem.need_throttle = false;
5375
5376				goto retry_flip;
5377			}
5378
5379			xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
5380				   "page flipping failed, on CRTC:%d (pipe=%d), disabling %s page flips\n",
5381				   crtc->id, crtc->pipe, data ? "synchronous": "asynchronous");
5382			sna->flags &= ~(data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP);
5383			goto fixup_flip;
5384		}
5385
5386		if (data) {
5387			assert(crtc->flip_bo == NULL);
5388			crtc->flip_handler = handler;
5389			crtc->flip_data = data;
5390			crtc->flip_bo = kgem_bo_reference(bo);
5391			crtc->flip_bo->active_scanout++;
5392			crtc->flip_serial = crtc->mode_serial;
5393			crtc->flip_pending = true;
5394			sna->mode.flip_active++;
5395		}
5396
5397next_crtc:
5398		count++;
5399	}
5400
5401	DBG(("%s: page flipped %d crtcs\n", __FUNCTION__, count));
5402	return count;
5403}
5404
5405static const xf86CrtcConfigFuncsRec sna_mode_funcs = {
5406	sna_mode_resize
5407};
5408
5409static void set_size_range(struct sna *sna)
5410{
5411	/* We lie slightly as we expect no single monitor to exceed the
5412	 * crtc limits, so if the mode exceeds the scanout restrictions,
5413	 * we will quietly convert that to per-crtc pixmaps.
5414	 */
5415	xf86CrtcSetSizeRange(sna->scrn, 8, 8, INT16_MAX, INT16_MAX);
5416}
5417
5418#if HAS_GAMMA
5419static void set_gamma(uint16_t *curve, int size, double value)
5420{
5421	int i;
5422
5423	value = 1/value;
5424	for (i = 0; i < size; i++)
5425		curve[i] = 256*(size-1)*pow(i/(double)(size-1), value);
5426}
5427
5428static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc)
5429{
5430	XF86ConfMonitorPtr mon = output->conf_monitor;
5431
5432	if (!mon)
5433		return;
5434
5435	DBG(("%s: red=%f\n", __FUNCTION__, mon->mon_gamma_red));
5436	if (mon->mon_gamma_red >= GAMMA_MIN &&
5437	    mon->mon_gamma_red <= GAMMA_MAX &&
5438	    mon->mon_gamma_red != 1.0)
5439		set_gamma(crtc->gamma_red, crtc->gamma_size,
5440			  mon->mon_gamma_red);
5441
5442	DBG(("%s: green=%f\n", __FUNCTION__, mon->mon_gamma_green));
5443	if (mon->mon_gamma_green >= GAMMA_MIN &&
5444	    mon->mon_gamma_green <= GAMMA_MAX &&
5445	    mon->mon_gamma_green != 1.0)
5446		set_gamma(crtc->gamma_green, crtc->gamma_size,
5447			  mon->mon_gamma_green);
5448
5449	DBG(("%s: blue=%f\n", __FUNCTION__, mon->mon_gamma_blue));
5450	if (mon->mon_gamma_blue >= GAMMA_MIN &&
5451	    mon->mon_gamma_blue <= GAMMA_MAX &&
5452	    mon->mon_gamma_blue != 1.0)
5453		set_gamma(crtc->gamma_blue, crtc->gamma_size,
5454			  mon->mon_gamma_blue);
5455}
5456
5457static void crtc_init_gamma(xf86CrtcPtr crtc)
5458{
5459	uint16_t *gamma;
5460
5461	/* Initialize the gamma ramps */
5462	gamma = NULL;
5463	if (crtc->gamma_size == 256)
5464		gamma = crtc->gamma_red;
5465	if (gamma == NULL)
5466		gamma = malloc(3 * 256 * sizeof(uint16_t));
5467	if (gamma) {
5468		struct sna *sna = to_sna(crtc->scrn);
5469		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
5470		struct drm_mode_crtc_lut lut;
5471		bool gamma_set = false;
5472
5473		assert(sna_crtc);
5474
5475		lut.crtc_id = sna_crtc->id;
5476		lut.gamma_size = 256;
5477		lut.red = (uintptr_t)(gamma);
5478		lut.green = (uintptr_t)(gamma + 256);
5479		lut.blue = (uintptr_t)(gamma + 2 * 256);
5480		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) == 0) {
5481			VG(VALGRIND_MAKE_MEM_DEFINED(gamma, 3*256*sizeof(gamma[0])));
5482			gamma_set =
5483				gamma[256 - 1] &&
5484				gamma[2*256 - 1] &&
5485				gamma[3*256 - 1];
5486		}
5487
5488		DBG(("%s: CRTC:%d, pipe=%d: gamma set?=%d\n",
5489		     __FUNCTION__, sna_crtc->id, sna_crtc->pipe,
5490		     gamma_set));
5491		if (!gamma_set) {
5492			int i;
5493
5494			for (i = 0; i < 256; i++) {
5495				gamma[i] = i << 8;
5496				gamma[256 + i] = i << 8;
5497				gamma[2*256 + i] = i << 8;
5498			}
5499		}
5500
5501		if (gamma != crtc->gamma_red) {
5502			free(crtc->gamma_red);
5503			crtc->gamma_red = gamma;
5504			crtc->gamma_green = gamma + 256;
5505			crtc->gamma_blue = gamma + 2*256;
5506		}
5507	}
5508}
5509#else
5510static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc) { }
5511static void crtc_init_gamma(xf86CrtcPtr crtc) { }
5512#endif
5513
5514static const char *preferred_mode(xf86OutputPtr output)
5515{
5516	const char *mode;
5517
5518	mode = xf86GetOptValString(output->options, OPTION_PREFERRED_MODE);
5519	if (mode)
5520		return mode;
5521
5522	if (output->scrn->display->modes && *output->scrn->display->modes)
5523		return *output->scrn->display->modes;
5524
5525	return NULL;
5526}
5527
5528static bool sna_probe_initial_configuration(struct sna *sna)
5529{
5530	ScrnInfoPtr scrn = sna->scrn;
5531	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
5532	int width, height;
5533	int i, j;
5534
5535	assert((sna->flags & SNA_IS_HOSTED) == 0);
5536
5537	if ((sna->flags & SNA_IS_SLAVED) == 0) {
5538		const int user_overrides[] = {
5539			OPTION_POSITION,
5540			OPTION_BELOW,
5541			OPTION_RIGHT_OF,
5542			OPTION_ABOVE,
5543			OPTION_LEFT_OF,
5544			OPTION_ROTATE,
5545			OPTION_PANNING,
5546		};
5547		if (xf86ReturnOptValBool(sna->Options, OPTION_REPROBE, FALSE)) {
5548			DBG(("%s: user requests reprobing\n", __FUNCTION__));
5549			return false;
5550		}
5551
5552		/* First scan through all outputs and look for user overrides */
5553		for (i = 0; i < sna->mode.num_real_output; i++) {
5554			xf86OutputPtr output = config->output[i];
5555
5556			for (j = 0; j < ARRAY_SIZE(user_overrides); j++) {
5557				if (xf86GetOptValString(output->options, user_overrides[j])) {
5558					DBG(("%s: user placement [%d] for %s\n",
5559					     __FUNCTION__,
5560					     user_overrides[j],
5561					     output->name));
5562					return false;
5563				}
5564			}
5565		}
5566	}
5567
5568	/* Copy the existing modes on each CRTCs */
5569	for (i = 0; i < sna->mode.num_real_crtc; i++) {
5570		xf86CrtcPtr crtc = config->crtc[i];
5571		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
5572		struct drm_mode_crtc mode;
5573
5574		crtc->enabled = FALSE;
5575		crtc->desiredMode.status = MODE_NOMODE;
5576
5577		crtc_init_gamma(crtc);
5578
5579		/* Retrieve the current mode */
5580		VG_CLEAR(mode);
5581		mode.crtc_id = sna_crtc->id;
5582		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode))
5583			continue;
5584
5585		DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__,
5586		     sna_crtc->id, sna_crtc->pipe,
5587		     mode.mode_valid && mode.mode.clock));
5588
5589		if (!mode.mode_valid || mode.mode.clock == 0)
5590			continue;
5591
5592		mode_from_kmode(scrn, &mode.mode, &crtc->desiredMode);
5593		crtc->desiredRotation = sna_crtc->primary.rotation.current;
5594		crtc->desiredX = mode.x;
5595		crtc->desiredY = mode.y;
5596		crtc->desiredTransformPresent = FALSE;
5597	}
5598
5599	/* Reconstruct outputs pointing to active CRTC */
5600	for (i = 0; i < sna->mode.num_real_output; i++) {
5601		xf86OutputPtr output = config->output[i];
5602		uint32_t crtc_id;
5603
5604		assert(to_sna_output(output));
5605
5606		crtc_id = (uintptr_t)output->crtc;
5607		output->crtc = NULL;
5608		if (sna->flags & SNA_IS_SLAVED)
5609			continue;
5610
5611		if (crtc_id == 0) {
5612			DBG(("%s: not using output %s, disconnected\n",
5613			     __FUNCTION__, output->name));
5614			continue;
5615		}
5616
5617		if (xf86ReturnOptValBool(output->options, OPTION_DISABLE, 0)) {
5618			DBG(("%s: not using output %s, manually disabled\n",
5619			     __FUNCTION__, output->name));
5620			continue;
5621		}
5622
5623		for (j = 0; j < sna->mode.num_real_crtc; j++) {
5624			xf86CrtcPtr crtc = config->crtc[j];
5625
5626			assert(to_sna_crtc(crtc));
5627			if (to_sna_crtc(crtc)->id != crtc_id)
5628				continue;
5629
5630			if (crtc->desiredMode.status == MODE_OK) {
5631				DisplayModePtr M;
5632				const char *pref;
5633
5634				pref = preferred_mode(output);
5635				if (pref && strcmp(pref, crtc->desiredMode.name)) {
5636					DBG(("%s: output %s user requests a different preferred mode %s, found %s\n",
5637					     __FUNCTION__, output->name, pref, crtc->desiredMode.name));
5638					return false;
5639				}
5640
5641				xf86DrvMsg(scrn->scrnIndex, X_PROBED,
5642					   "Output %s using initial mode %s on pipe %d\n",
5643					   output->name,
5644					   crtc->desiredMode.name,
5645					   to_sna_crtc(crtc)->pipe);
5646
5647				output->crtc = crtc;
5648				crtc->enabled = TRUE;
5649
5650				if (output->mm_width == 0 || output->mm_height == 0) {
5651					output->mm_height = (crtc->desiredMode.VDisplay * 254) / (10*DEFAULT_DPI);
5652					output->mm_width = (crtc->desiredMode.HDisplay * 254) / (10*DEFAULT_DPI);
5653				}
5654
5655				output_set_gamma(output, crtc);
5656
5657				M = calloc(1, sizeof(DisplayModeRec));
5658				if (M) {
5659					*M = crtc->desiredMode;
5660					M->name = strdup(M->name);
5661					output->probed_modes =
5662						xf86ModesAdd(output->probed_modes, M);
5663				}
5664			}
5665
5666			break;
5667		}
5668
5669		if (j == sna->mode.num_real_crtc) {
5670			/* Can not find the earlier associated CRTC, bail */
5671			DBG(("%s: existing setup conflicts with output assignment (Zaphod), reprobing\n",
5672			     __FUNCTION__));
5673			return false;
5674		}
5675	}
5676
5677	width = height = 0;
5678	for (i = 0; i < sna->mode.num_real_crtc; i++) {
5679		xf86CrtcPtr crtc = config->crtc[i];
5680		int w, h;
5681
5682		if (!crtc->enabled)
5683			continue;
5684
5685		w = crtc->desiredX + crtc->desiredMode.HDisplay;
5686		if (w > width)
5687			width = w;
5688		h = crtc->desiredY + crtc->desiredMode.VDisplay;
5689		if (h > height)
5690			height = h;
5691	}
5692
5693	/* Prefer the native panel size if any */
5694	if (!width || !height) {
5695		for (i = 0; i < sna->mode.num_real_output; i++) {
5696			xf86OutputPtr output = config->output[i];
5697			struct sna_output *sna_output = to_sna_output(output);
5698
5699			if (!sna_output->is_panel)
5700				continue;
5701
5702			DBG(("%s: querying panel '%s' for preferred unattached size\n",
5703			     __FUNCTION__, output->name));
5704
5705			if (sna_output_detect(output) != XF86OutputStatusConnected)
5706				continue;
5707
5708			if (sna_output->num_modes == 0)
5709				continue;
5710
5711			width = sna_output->modes[0].hdisplay;
5712			height= sna_output->modes[0].vdisplay;
5713
5714			DBG(("%s: panel '%s' is %dx%d\n",
5715			     __FUNCTION__, output->name, width, height));
5716			break;
5717		}
5718	}
5719
5720	if (!width || !height) {
5721		width = 1024;
5722		height = 768;
5723	}
5724
5725	scrn->display->frameX0 = 0;
5726	scrn->display->frameY0 = 0;
5727	scrn->display->virtualX = width;
5728	scrn->display->virtualY = height;
5729
5730	scrn->virtualX = width;
5731	scrn->virtualY = height;
5732
5733	xf86SetScrnInfoModes(sna->scrn);
5734	DBG(("%s: SetScrnInfoModes = %p\n", __FUNCTION__, scrn->modes));
5735	return scrn->modes != NULL;
5736}
5737
5738static void
5739sanitize_outputs(struct sna *sna)
5740{
5741	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5742	int i;
5743
5744	for (i = 0; i < config->num_output; i++)
5745		config->output[i]->crtc = NULL;
5746}
5747
5748static bool has_flip(struct sna *sna)
5749{
5750	drm_i915_getparam_t gp;
5751	int v;
5752
5753	if (sna->flags & SNA_NO_FLIP)
5754		return false;
5755
5756	v = 0;
5757
5758	VG_CLEAR(gp);
5759	gp.param = I915_PARAM_HAS_PAGEFLIPPING;
5760	gp.value = &v;
5761
5762	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GETPARAM, &gp))
5763		return false;
5764
5765	VG(VALGRIND_MAKE_MEM_DEFINED(&v, sizeof(v)));
5766	return v > 0;
5767}
5768
5769static bool has_flip__async(struct sna *sna)
5770{
5771#define DRM_CAP_ASYNC_PAGE_FLIP 0x7
5772	struct local_get_cap {
5773		uint64_t name;
5774		uint64_t value;
5775	} cap = { DRM_CAP_ASYNC_PAGE_FLIP };
5776
5777	if (sna->flags & SNA_NO_FLIP)
5778		return false;
5779
5780	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0)
5781		return cap.value > 0;
5782
5783	return false;
5784}
5785
5786static void
5787probe_capabilities(struct sna *sna)
5788{
5789	sna->flags &= ~(SNA_HAS_FLIP | SNA_HAS_ASYNC_FLIP);
5790	if (has_flip(sna))
5791		sna->flags |= SNA_HAS_FLIP;
5792	if (has_flip__async(sna))
5793		sna->flags |= SNA_HAS_ASYNC_FLIP;
5794	DBG(("%s: page flips? %s, async? %s\n", __FUNCTION__,
5795	     sna->flags & SNA_HAS_FLIP ? "enabled" : "disabled",
5796	     sna->flags & SNA_HAS_ASYNC_FLIP ? "enabled" : "disabled"));
5797}
5798
5799void
5800sna_crtc_config_notify(ScreenPtr screen)
5801{
5802	struct sna *sna = to_sna_from_screen(screen);
5803
5804	DBG(("%s(dirty?=%d)\n", __FUNCTION__, sna->mode.dirty));
5805	if (!sna->mode.dirty)
5806		return;
5807
5808	if (disable_unused_crtc(sna)) {
5809		/* This will have recursed, so simply bail at this point */
5810		assert(sna->mode.dirty == false);
5811#ifdef RANDR_12_INTERFACE
5812		xf86RandR12TellChanged(screen);
5813#endif
5814		return;
5815	}
5816
5817	update_flush_interval(sna);
5818	sna_cursors_reload(sna);
5819
5820	probe_capabilities(sna);
5821	sna_present_update(sna);
5822
5823	sna->mode.dirty = false;
5824}
5825
5826#if HAS_PIXMAP_SHARING
5827#define sna_setup_provider(scrn) xf86ProviderSetup(scrn, NULL, "Intel")
5828#else
5829#define sna_setup_provider(scrn)
5830#endif
5831
5832bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
5833{
5834	drmModeResPtr res;
5835	int num_fake = 0;
5836	int i;
5837
5838	if (sna->flags & SNA_IS_HOSTED) {
5839		sna_setup_provider(scrn);
5840		return true;
5841	}
5842
5843	probe_capabilities(sna);
5844
5845	if (!xf86GetOptValInteger(sna->Options, OPTION_VIRTUAL, &num_fake))
5846		num_fake = 1;
5847
5848	res = drmModeGetResources(sna->kgem.fd);
5849	if (res &&
5850	    (res->count_crtcs == 0 ||
5851	     res->count_encoders == 0 ||
5852	     res->count_connectors == 0)) {
5853		drmModeFreeResources(res);
5854		res = NULL;
5855	}
5856	if (res) {
5857		xf86CrtcConfigPtr xf86_config;
5858
5859		assert(res->count_crtcs);
5860		assert(res->count_connectors);
5861
5862		xf86CrtcConfigInit(scrn, &sna_mode_funcs);
5863
5864		xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
5865		xf86_config->xf86_crtc_notify = sna_crtc_config_notify;
5866
5867		for (i = 0; i < res->count_crtcs; i++)
5868			if (!sna_crtc_add(scrn, res->crtcs[i]))
5869				return false;
5870
5871		sna->mode.num_real_crtc = xf86_config->num_crtc;
5872
5873		sna->mode.num_real_encoder = res->count_encoders;
5874		sna->mode.encoders = res->encoders;
5875		res->encoders = NULL;
5876
5877		for (i = 0; i < res->count_connectors; i++)
5878			if (sna_output_add(sna, res->connectors[i], 0) < 0)
5879				return false;
5880
5881		sna->mode.num_real_output = xf86_config->num_output;
5882
5883		sna->mode.max_crtc_width  = res->max_width;
5884		sna->mode.max_crtc_height = res->max_height;
5885
5886		RegionEmpty(&sna->mode.shadow_region);
5887		RegionEmpty(&sna->mode.shadow_cancel);
5888		list_init(&sna->mode.shadow_crtc);
5889
5890		drmModeFreeResources(res);
5891
5892		sna_cursor_pre_init(sna);
5893		sna_backlight_pre_init(sna);
5894
5895		set_size_range(sna);
5896	} else {
5897		if (num_fake == 0)
5898			num_fake = 1;
5899	}
5900
5901	if (!sna_mode_fake_init(sna, num_fake))
5902		return false;
5903
5904	if (!sna_probe_initial_configuration(sna)) {
5905		xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
5906
5907		sanitize_outputs(sna);
5908		if (config->num_crtc && config->num_output) {
5909			if (!xf86ReturnOptValBool(config->output[0]->options,
5910						  OPTION_PRIMARY, FALSE))
5911				sort_config_outputs(sna);
5912			xf86InitialConfiguration(scrn, TRUE);
5913		}
5914	}
5915	sort_config_outputs(sna);
5916
5917	sna_setup_provider(scrn);
5918	return scrn->modes != NULL;
5919}
5920
5921bool
5922sna_mode_wants_tear_free(struct sna *sna)
5923{
5924	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5925	int i;
5926
5927	for (i = 0; i < sna->mode.num_real_output; i++) {
5928		struct sna_output *output = to_sna_output(config->output[i]);
5929		int id = find_property(sna, output, "Panel Self-Refresh");
5930		if (id !=-1 && output->prop_values[id] != -1) {
5931			DBG(("%s: Panel Self-Refresh detected on %s\n",
5932			     __FUNCTION__, config->output[i]->name));
5933			return true;
5934		}
5935	}
5936
5937	return false;
5938}
5939
5940void
5941sna_mode_set_primary(struct sna *sna)
5942{
5943#ifdef RANDR_12_INTERFACE
5944	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5945	rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn));
5946	int i;
5947
5948	if (rr == NULL || rr->primaryOutput)
5949		return;
5950
5951	for (i = 0; i < sna->mode.num_real_output; i++) {
5952		xf86OutputPtr output = config->output[i];
5953
5954		if (!xf86ReturnOptValBool(output->options, OPTION_PRIMARY, FALSE))
5955			continue;
5956
5957		DBG(("%s: setting PrimaryOutput %s\n", __FUNCTION__, output->name));
5958		rr->primaryOutput = output->randr_output;
5959		RROutputChanged(rr->primaryOutput, 0);
5960		rr->layoutChanged = TRUE;
5961		break;
5962	}
5963#endif
5964}
5965
5966bool
5967sna_mode_disable(struct sna *sna)
5968{
5969	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5970	int i;
5971
5972	if (sna->flags & SNA_IS_HOSTED)
5973		return false;
5974
5975	if (!sna->scrn->vtSema)
5976		return false;
5977
5978	/* XXX we will cause previously hidden cursors to be reshown, but
5979	 * this should be a rare fixup case for severe fragmentation.
5980	 */
5981	sna_hide_cursors(sna->scrn);
5982	for (i = 0; i < sna->mode.num_real_crtc; i++)
5983		sna_crtc_disable(config->crtc[i]);
5984	assert(sna->mode.front_active == 0);
5985
5986	sna_mode_wakeup(sna);
5987	kgem_clean_scanout_cache(&sna->kgem);
5988	return true;
5989}
5990
5991void
5992sna_mode_enable(struct sna *sna)
5993{
5994	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5995	int i;
5996
5997	DBG(("%s\n", __FUNCTION__));
5998
5999	if (sna->flags & SNA_IS_HOSTED)
6000		return;
6001
6002	if (!sna->scrn->vtSema)
6003		return;
6004
6005	for (i = 0; i < sna->mode.num_real_crtc; i++) {
6006		xf86CrtcPtr crtc = config->crtc[i];
6007
6008		DBG(("%s: crtc[%d].enabled?=%d\n", __FUNCTION__, i, crtc->enabled));
6009		assert(to_sna_crtc(crtc) != NULL);
6010		if (!crtc->enabled)
6011			continue;
6012
6013		if (crtc->mode.Clock == 0)
6014			continue;
6015
6016		__sna_crtc_set_mode(crtc);
6017	}
6018
6019	update_flush_interval(sna);
6020	sna_show_cursors(sna->scrn);
6021	sna->mode.dirty = false;
6022}
6023
6024void
6025sna_mode_close(struct sna *sna)
6026{
6027	sna_mode_wakeup(sna);
6028
6029	if (sna->flags & SNA_IS_HOSTED)
6030		return;
6031
6032	sna_mode_reset(sna);
6033
6034	sna_cursor_close(sna);
6035	sna_cursors_fini(sna);
6036
6037	sna_backlight_close(sna);
6038	sna->mode.dirty = false;
6039}
6040
6041void
6042sna_mode_fini(struct sna *sna)
6043{
6044	free(sna->mode.encoders);
6045}
6046
6047static bool sna_box_intersect(BoxPtr r, const BoxRec *a, const BoxRec *b)
6048{
6049	r->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
6050	r->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
6051	if (r->x1 >= r->x2)
6052		return false;
6053
6054	r->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
6055	r->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
6056	DBG(("%s: (%d, %d), (%d, %d) intersect (%d, %d), (%d, %d) = (%d, %d), (%d, %d)\n",
6057	     __FUNCTION__,
6058	     a->x1, a->y1, a->x2, a->y2,
6059	     b->x1, b->y1, b->x2, b->y2,
6060	     r->x1, r->y1, r->x2, r->y2));
6061	if (r->y1 >= r->y2)
6062		return false;
6063
6064	return true;
6065}
6066
6067static int sna_box_area(const BoxRec *box)
6068{
6069	return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1);
6070}
6071
6072/*
6073 * Return the crtc covering 'box'. If two crtcs cover a portion of
6074 * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
6075 * with greater coverage
6076 */
6077xf86CrtcPtr
6078sna_covering_crtc(struct sna *sna, const BoxRec *box, xf86CrtcPtr desired)
6079{
6080	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
6081	xf86CrtcPtr best_crtc;
6082	int best_coverage, c;
6083
6084	if (sna->flags & SNA_IS_HOSTED)
6085		return NULL;
6086
6087	/* If we do not own the VT, we do not own the CRTC either */
6088	if (!sna->scrn->vtSema)
6089		return NULL;
6090
6091	DBG(("%s for box=(%d, %d), (%d, %d)\n",
6092	     __FUNCTION__, box->x1, box->y1, box->x2, box->y2));
6093
6094	if (desired == NULL) {
6095		rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn));
6096		if (rr && rr->primaryOutput) {
6097			xf86OutputPtr output = rr->primaryOutput->devPrivate;
6098			DBG(("%s: have PrimaryOutput? %d marking as desired\n", __FUNCTION__, output->crtc != NULL));
6099			desired = output->crtc;
6100		}
6101	}
6102	if (desired && to_sna_crtc(desired) && to_sna_crtc(desired)->bo) {
6103		BoxRec cover_box;
6104		if (sna_box_intersect(&cover_box, &desired->bounds, box)) {
6105			DBG(("%s: box overlaps desired crtc: (%d, %d), (%d, %d)\n",
6106			     __FUNCTION__,
6107			     cover_box.x1, cover_box.y1,
6108			     cover_box.x2, cover_box.y2));
6109			return desired;
6110		}
6111	}
6112
6113	best_crtc = NULL;
6114	best_coverage = 0;
6115	for (c = 0; c < sna->mode.num_real_crtc; c++) {
6116		xf86CrtcPtr crtc = config->crtc[c];
6117		BoxRec cover_box;
6118		int coverage;
6119
6120		assert(to_sna_crtc(crtc));
6121
6122		/* If the CRTC is off, treat it as not covering */
6123		if (to_sna_crtc(crtc)->bo == NULL) {
6124			DBG(("%s: crtc %d off, skipping\n", __FUNCTION__, c));
6125			continue;
6126		}
6127
6128		DBG(("%s: crtc %d: (%d, %d), (%d, %d)\n",
6129		     __FUNCTION__, c,
6130		     crtc->bounds.x1, crtc->bounds.y1,
6131		     crtc->bounds.x2, crtc->bounds.y2));
6132		if (*(const uint64_t *)box == *(uint64_t *)&crtc->bounds) {
6133			DBG(("%s: box exactly matches crtc [%d]\n",
6134			     __FUNCTION__, c));
6135			return crtc;
6136		}
6137
6138		if (!sna_box_intersect(&cover_box, &crtc->bounds, box))
6139			continue;
6140
6141		DBG(("%s: box instersects (%d, %d), (%d, %d) of crtc %d\n",
6142		     __FUNCTION__,
6143		     cover_box.x1, cover_box.y1,
6144		     cover_box.x2, cover_box.y2,
6145		     c));
6146
6147		coverage = sna_box_area(&cover_box);
6148		DBG(("%s: box covers %d of crtc %d\n",
6149		     __FUNCTION__, coverage, c));
6150		if (coverage > best_coverage) {
6151			best_crtc = crtc;
6152			best_coverage = coverage;
6153		}
6154	}
6155	DBG(("%s: best crtc = %p, coverage = %d\n",
6156	     __FUNCTION__, best_crtc, best_coverage));
6157	return best_crtc;
6158}
6159
6160#define MI_LOAD_REGISTER_IMM			(0x22<<23)
6161
6162static bool sna_emit_wait_for_scanline_hsw(struct sna *sna,
6163					   xf86CrtcPtr crtc,
6164					   int pipe, int y1, int y2,
6165					   bool full_height)
6166{
6167	uint32_t event;
6168	uint32_t *b;
6169
6170	if (!sna->kgem.has_secure_batches)
6171		return false;
6172
6173	b = kgem_get_batch(&sna->kgem);
6174	sna->kgem.nbatch += 17;
6175
6176	switch (pipe) {
6177	default: assert(0);
6178	case 0: event = 1 << 0; break;
6179	case 1: event = 1 << 8; break;
6180	case 2: event = 1 << 14; break;
6181	}
6182
6183	b[0] = MI_LOAD_REGISTER_IMM | 1;
6184	b[1] = 0x44050; /* DERRMR */
6185	b[2] = ~event;
6186	b[3] = MI_LOAD_REGISTER_IMM | 1;
6187	b[4] = 0xa188; /* FORCEWAKE_MT */
6188	b[5] = 2 << 16 | 2;
6189
6190	/* The documentation says that the LOAD_SCAN_LINES command
6191	 * always comes in pairs. Don't ask me why. */
6192	switch (pipe) {
6193	default: assert(0);
6194	case 0: event = 0 << 19; break;
6195	case 1: event = 1 << 19; break;
6196	case 2: event = 4 << 19; break;
6197	}
6198	b[8] = b[6] = MI_LOAD_SCAN_LINES_INCL | event;
6199	b[9] = b[7] = (y1 << 16) | (y2-1);
6200
6201	switch (pipe) {
6202	default: assert(0);
6203	case 0: event = 1 << 0; break;
6204	case 1: event = 1 << 8; break;
6205	case 2: event = 1 << 14; break;
6206	}
6207	b[10] = MI_WAIT_FOR_EVENT | event;
6208
6209	b[11] = MI_LOAD_REGISTER_IMM | 1;
6210	b[12] = 0xa188; /* FORCEWAKE_MT */
6211	b[13] = 2 << 16;
6212	b[14] = MI_LOAD_REGISTER_IMM | 1;
6213	b[15] = 0x44050; /* DERRMR */
6214	b[16] = ~0;
6215
6216	sna->kgem.batch_flags |= I915_EXEC_SECURE;
6217	return true;
6218}
6219
6220static bool sna_emit_wait_for_scanline_ivb(struct sna *sna,
6221					   xf86CrtcPtr crtc,
6222					   int pipe, int y1, int y2,
6223					   bool full_height)
6224{
6225	uint32_t event, *b;
6226
6227	if (!sna->kgem.has_secure_batches)
6228		return false;
6229
6230	assert(y1 >= 0);
6231	assert(y2 > y1);
6232	assert(sna->kgem.mode);
6233
6234	/* Always program one less than the desired value */
6235	if (--y1 < 0)
6236		y1 = crtc->bounds.y2;
6237	y2--;
6238
6239	switch (pipe) {
6240	default:
6241		assert(0);
6242	case 0:
6243		event = 1 << (full_height ? 3 : 0);
6244		break;
6245	case 1:
6246		event = 1 << (full_height ? 11 : 8);
6247		break;
6248	case 2:
6249		event = 1 << (full_height ? 21 : 14);
6250		break;
6251	}
6252
6253	b = kgem_get_batch(&sna->kgem);
6254
6255	/* Both the LRI and WAIT_FOR_EVENT must be in the same cacheline */
6256	if (((sna->kgem.nbatch + 6) >> 4) != (sna->kgem.nbatch + 10) >> 4) {
6257		int dw = sna->kgem.nbatch + 6;
6258		dw = ALIGN(dw, 16) - dw;
6259		while (dw--)
6260			*b++ = MI_NOOP;
6261	}
6262
6263	b[0] = MI_LOAD_REGISTER_IMM | 1;
6264	b[1] = 0x44050; /* DERRMR */
6265	b[2] = ~event;
6266	b[3] = MI_LOAD_REGISTER_IMM | 1;
6267	b[4] = 0xa188; /* FORCEWAKE_MT */
6268	b[5] = 2 << 16 | 2;
6269	b[6] = MI_LOAD_REGISTER_IMM | 1;
6270	b[7] = 0x70068 + 0x1000 * pipe;
6271	b[8] = (1 << 31) | (1 << 30) | (y1 << 16) | y2;
6272	b[9] = MI_WAIT_FOR_EVENT | event;
6273	b[10] = MI_LOAD_REGISTER_IMM | 1;
6274	b[11] = 0xa188; /* FORCEWAKE_MT */
6275	b[12] = 2 << 16;
6276	b[13] = MI_LOAD_REGISTER_IMM | 1;
6277	b[14] = 0x44050; /* DERRMR */
6278	b[15] = ~0;
6279
6280	sna->kgem.nbatch = b - sna->kgem.batch + 16;
6281
6282	sna->kgem.batch_flags |= I915_EXEC_SECURE;
6283	return true;
6284}
6285
6286static bool sna_emit_wait_for_scanline_gen6(struct sna *sna,
6287					    xf86CrtcPtr crtc,
6288					    int pipe, int y1, int y2,
6289					    bool full_height)
6290{
6291	uint32_t *b;
6292	uint32_t event;
6293
6294	if (!sna->kgem.has_secure_batches)
6295		return false;
6296
6297	assert(y1 >= 0);
6298	assert(y2 > y1);
6299	assert(sna->kgem.mode == KGEM_RENDER);
6300
6301	/* Always program one less than the desired value */
6302	if (--y1 < 0)
6303		y1 = crtc->bounds.y2;
6304	y2--;
6305
6306	/* The scanline granularity is 3 bits */
6307	y1 &= ~7;
6308	y2 &= ~7;
6309	if (y2 == y1)
6310		return false;
6311
6312	event = 1 << (3*full_height + pipe*8);
6313
6314	b = kgem_get_batch(&sna->kgem);
6315	sna->kgem.nbatch += 16;
6316
6317	b[0] = MI_LOAD_REGISTER_IMM | 1;
6318	b[1] = 0x44050; /* DERRMR */
6319	b[2] = ~event;
6320	b[3] = MI_LOAD_REGISTER_IMM | 1;
6321	b[4] = 0x4f100; /* magic */
6322	b[5] = (1 << 31) | (1 << 30) | pipe << 29 | (y1 << 16) | y2;
6323	b[6] = MI_LOAD_REGISTER_IMM | 1;
6324	b[7] = 0x2050; /* PSMI_CTL(rcs) */
6325	b[8] = 1 << 16 | 1;
6326	b[9] = MI_WAIT_FOR_EVENT | event;
6327	b[10] = MI_LOAD_REGISTER_IMM | 1;
6328	b[11] = 0x2050; /* PSMI_CTL(rcs) */
6329	b[12] = 1 << 16;
6330	b[13] = MI_LOAD_REGISTER_IMM | 1;
6331	b[14] = 0x44050; /* DERRMR */
6332	b[15] = ~0;
6333
6334	sna->kgem.batch_flags |= I915_EXEC_SECURE;
6335	return true;
6336}
6337
6338static bool sna_emit_wait_for_scanline_gen4(struct sna *sna,
6339					    xf86CrtcPtr crtc,
6340					    int pipe, int y1, int y2,
6341					    bool full_height)
6342{
6343	uint32_t event;
6344	uint32_t *b;
6345
6346	if (pipe == 0) {
6347		if (full_height)
6348			event = MI_WAIT_FOR_PIPEA_SVBLANK;
6349		else
6350			event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
6351	} else {
6352		if (full_height)
6353			event = MI_WAIT_FOR_PIPEB_SVBLANK;
6354		else
6355			event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
6356	}
6357
6358	b = kgem_get_batch(&sna->kgem);
6359	sna->kgem.nbatch += 5;
6360
6361	/* The documentation says that the LOAD_SCAN_LINES command
6362	 * always comes in pairs. Don't ask me why. */
6363	b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20;
6364	b[3] = b[1] = (y1 << 16) | (y2-1);
6365	b[4] = MI_WAIT_FOR_EVENT | event;
6366
6367	return true;
6368}
6369
6370static bool sna_emit_wait_for_scanline_gen2(struct sna *sna,
6371					    xf86CrtcPtr crtc,
6372					    int pipe, int y1, int y2,
6373					    bool full_height)
6374{
6375	uint32_t *b;
6376
6377	/*
6378	 * Pre-965 doesn't have SVBLANK, so we need a bit
6379	 * of extra time for the blitter to start up and
6380	 * do its job for a full height blit
6381	 */
6382	if (full_height)
6383		y2 -= 2;
6384
6385	b = kgem_get_batch(&sna->kgem);
6386	sna->kgem.nbatch += 5;
6387
6388	/* The documentation says that the LOAD_SCAN_LINES command
6389	 * always comes in pairs. Don't ask me why. */
6390	b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20;
6391	b[3] = b[1] = (y1 << 16) | (y2-1);
6392	b[4] = MI_WAIT_FOR_EVENT | 1 << (1 + 4*pipe);
6393
6394	return true;
6395}
6396
6397bool
6398sna_wait_for_scanline(struct sna *sna,
6399		      PixmapPtr pixmap,
6400		      xf86CrtcPtr crtc,
6401		      const BoxRec *clip)
6402{
6403	bool full_height;
6404	int y1, y2, pipe;
6405	bool ret;
6406
6407	assert(crtc != NULL);
6408	assert(to_sna_crtc(crtc) != NULL);
6409	assert(to_sna_crtc(crtc)->bo != NULL);
6410	assert(pixmap == sna->front);
6411
6412	if (sna->flags & SNA_NO_VSYNC)
6413		return false;
6414
6415	/*
6416	 * Make sure we don't wait for a scanline that will
6417	 * never occur
6418	 */
6419	y1 = clip->y1 - crtc->bounds.y1;
6420	if (y1 < 0)
6421		y1 = 0;
6422	y2 = clip->y2 - crtc->bounds.y1;
6423	if (y2 > crtc->bounds.y2 - crtc->bounds.y1)
6424		y2 = crtc->bounds.y2 - crtc->bounds.y1;
6425	DBG(("%s: clipped range = %d, %d\n", __FUNCTION__, y1, y2));
6426	if (y2 <= y1 + 4)
6427		return false;
6428
6429	full_height = y1 == 0 && y2 == crtc->bounds.y2 - crtc->bounds.y1;
6430
6431	if (crtc->mode.Flags & V_INTERLACE) {
6432		/* DSL count field lines */
6433		y1 /= 2;
6434		y2 /= 2;
6435	}
6436
6437	pipe = sna_crtc_to_pipe(crtc);
6438	DBG(("%s: pipe=%d, y1=%d, y2=%d, full_height?=%d\n",
6439	     __FUNCTION__, pipe, y1, y2, full_height));
6440
6441	if (sna->kgem.gen >= 0110)
6442		ret = false;
6443	else if (sna->kgem.gen == 0101)
6444		ret = false; /* chv, vsync method unknown */
6445	else if (sna->kgem.gen >= 075)
6446		ret = sna_emit_wait_for_scanline_hsw(sna, crtc, pipe, y1, y2, full_height);
6447	else if (sna->kgem.gen == 071)
6448		ret = false; /* vlv, vsync method unknown */
6449	else if (sna->kgem.gen >= 070)
6450		ret = sna_emit_wait_for_scanline_ivb(sna, crtc, pipe, y1, y2, full_height);
6451	else if (sna->kgem.gen >= 060)
6452		ret =sna_emit_wait_for_scanline_gen6(sna, crtc, pipe, y1, y2, full_height);
6453	else if (sna->kgem.gen >= 040)
6454		ret = sna_emit_wait_for_scanline_gen4(sna, crtc, pipe, y1, y2, full_height);
6455	else
6456		ret = sna_emit_wait_for_scanline_gen2(sna, crtc, pipe, y1, y2, full_height);
6457
6458	return ret;
6459}
6460
6461void sna_mode_check(struct sna *sna)
6462{
6463	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
6464	int i;
6465
6466	if (sna->flags & SNA_IS_HOSTED)
6467		return;
6468
6469	DBG(("%s\n", __FUNCTION__));
6470
6471	/* Validate CRTC attachments and force consistency upon the kernel */
6472	for (i = 0; i < sna->mode.num_real_crtc; i++) {
6473		xf86CrtcPtr crtc = config->crtc[i];
6474		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
6475		struct drm_mode_crtc mode;
6476		uint32_t expected[2];
6477
6478		assert(sna_crtc);
6479
6480#if XF86_CRTC_VERSION >= 3
6481		assert(sna_crtc->bo == NULL || crtc->active);
6482#endif
6483		expected[0] = sna_crtc->bo ? fb_id(sna_crtc->bo) : 0;
6484		expected[1] = sna_crtc->flip_bo ? fb_id(sna_crtc->flip_bo) : -1;
6485
6486		VG_CLEAR(mode);
6487		mode.crtc_id = sna_crtc->id;
6488		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode))
6489			continue;
6490
6491		DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=(%d or %d)\n",
6492		     __FUNCTION__,
6493		     mode.crtc_id, mode.mode_valid,
6494		     mode.fb_id, expected[0], expected[1]));
6495
6496		if (mode.fb_id != expected[0] && mode.fb_id != expected[1]) {
6497			xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
6498				   "%s: invalid state found on pipe %d, disabling CRTC:%d\n",
6499				   __FUNCTION__, sna_crtc->pipe, sna_crtc->id);
6500			sna_crtc_disable(crtc);
6501		}
6502	}
6503
6504	for (i = 0; i < config->num_output; i++) {
6505		xf86OutputPtr output = config->output[i];
6506		struct sna_output *sna_output;
6507
6508		if (output->crtc)
6509			continue;
6510
6511		sna_output = to_sna_output(output);
6512		if (sna_output == NULL)
6513			continue;
6514
6515		sna_output->dpms_mode = DPMSModeOff;
6516	}
6517
6518	update_flush_interval(sna);
6519}
6520
6521static bool
6522sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc)
6523{
6524#define LOCAL_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct local_mode_set_plane)
6525	struct local_mode_set_plane {
6526		uint32_t plane_id;
6527		uint32_t crtc_id;
6528		uint32_t fb_id; /* fb object contains surface format type */
6529		uint32_t flags;
6530
6531		/* Signed dest location allows it to be partially off screen */
6532		int32_t crtc_x, crtc_y;
6533		uint32_t crtc_w, crtc_h;
6534
6535		/* Source values are 16.16 fixed point */
6536		uint32_t src_x, src_y;
6537		uint32_t src_h, src_w;
6538	} s;
6539
6540	if (crtc->primary.id == 0)
6541		return false;
6542
6543	memset(&s, 0, sizeof(s));
6544	s.plane_id = crtc->primary.id;
6545	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
6546		return false;
6547
6548	s.plane_id = crtc->sprite.id;
6549	(void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s);
6550
6551	__sna_crtc_disable(sna, crtc);
6552	return true;
6553}
6554
6555void sna_mode_reset(struct sna *sna)
6556{
6557	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
6558	int i;
6559
6560	if (sna->flags & SNA_IS_HOSTED)
6561		return;
6562
6563	DBG(("%s\n", __FUNCTION__));
6564
6565	sna_hide_cursors(sna->scrn);
6566	for (i = 0; i < sna->mode.num_real_crtc; i++)
6567		if (!sna_crtc_hide_planes(sna, to_sna_crtc(config->crtc[i])))
6568			sna_crtc_disable(config->crtc[i]);
6569	assert(sna->mode.front_active == 0);
6570
6571	for (i = 0; i < sna->mode.num_real_crtc; i++) {
6572		struct sna_crtc *sna_crtc = to_sna_crtc(config->crtc[i]);
6573
6574		assert(sna_crtc != NULL);
6575		sna_crtc->dpms_mode = -1;
6576
6577		/* Force the rotation property to be reset on next use */
6578		rotation_reset(&sna_crtc->primary);
6579		rotation_reset(&sna_crtc->sprite);
6580	}
6581
6582	/* VT switching, likely to be fbcon so make the backlight usable */
6583	for (i = 0; i < sna->mode.num_real_output; i++) {
6584		struct sna_output *sna_output = to_sna_output(config->output[i]);
6585
6586		assert(sna_output != NULL);
6587		if (sna_output->dpms_mode != DPMSModeOff)
6588			continue;
6589
6590		if (!sna_output->backlight.iface)
6591			continue;
6592
6593		sna_output_backlight_set(sna_output,
6594					 sna_output->backlight_active_level);
6595	}
6596
6597	/* drain the event queue */
6598	sna_mode_wakeup(sna);
6599}
6600
6601static void transformed_box(BoxRec *box, xf86CrtcPtr crtc)
6602{
6603	box->x1 -= crtc->filter_width >> 1;
6604	box->x2 += crtc->filter_width >> 1;
6605	box->y1 -= crtc->filter_height >> 1;
6606	box->y2 += crtc->filter_height >> 1;
6607
6608	pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc, box);
6609
6610	if (box->x1 < 0)
6611		box->x1 = 0;
6612	if (box->y1 < 0)
6613		box->y1 = 0;
6614	if (box->x2 > crtc->mode.HDisplay)
6615		box->x2 = crtc->mode.HDisplay;
6616	if (box->y2 > crtc->mode.VDisplay)
6617		box->y2 = crtc->mode.VDisplay;
6618}
6619
6620inline static DrawablePtr crtc_source(xf86CrtcPtr crtc, int16_t *sx, int16_t *sy)
6621{
6622	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
6623	if (sna_crtc->slave_pixmap) {
6624		DBG(("%s: using slave pixmap=%ld, offset (%d, %d)\n",
6625		     __FUNCTION__,
6626		     sna_crtc->slave_pixmap->drawable.serialNumber,
6627		 -crtc->x, -crtc->y));
6628		*sx = -crtc->x;
6629		*sy = -crtc->y;
6630		return &sna_crtc->slave_pixmap->drawable;
6631	} else {
6632		DBG(("%s: using Screen pixmap=%ld\n",
6633		     __FUNCTION__,
6634		     to_sna(crtc->scrn)->front->drawable.serialNumber));
6635		*sx = *sy = 0;
6636		return &to_sna(crtc->scrn)->front->drawable;
6637	}
6638}
6639
6640static void
6641sna_crtc_redisplay__fallback(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo)
6642{
6643	int16_t sx, sy;
6644	struct sna *sna = to_sna(crtc->scrn);
6645	ScreenPtr screen = sna->scrn->pScreen;
6646	DrawablePtr draw = crtc_source(crtc, &sx, &sy);
6647	PictFormatPtr format;
6648	PicturePtr src, dst;
6649	PixmapPtr pixmap;
6650	int depth, error;
6651	void *ptr;
6652
6653	DBG(("%s: compositing transformed damage boxes, target handle=%d\n", __FUNCTION__, bo->handle));
6654
6655	error = sna_render_format_for_depth(draw->depth);
6656	depth = PIXMAN_FORMAT_DEPTH(error);
6657	format = PictureMatchFormat(screen, depth, error);
6658	if (format == NULL) {
6659		DBG(("%s: can't find format for depth=%d [%08x]\n",
6660		     __FUNCTION__, depth, error));
6661		return;
6662	}
6663
6664	DBG(("%s: dst format=%08x, depth=%d, bpp=%d, pitch=%d, size=%dx%d\n",
6665	     __FUNCTION__, format->format, depth, draw->bitsPerPixel,
6666	     bo->pitch, crtc->mode.HDisplay, crtc->mode.VDisplay));
6667
6668	ptr = kgem_bo_map__gtt(&sna->kgem, bo);
6669	if (ptr == NULL)
6670		return;
6671
6672	pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth);
6673	if (pixmap == NullPixmap)
6674		return;
6675
6676	if (!screen->ModifyPixmapHeader(pixmap,
6677					crtc->mode.HDisplay, crtc->mode.VDisplay,
6678					depth, draw->bitsPerPixel,
6679					bo->pitch, ptr))
6680		goto free_pixmap;
6681
6682	src = CreatePicture(None, draw, format,
6683			    0, NULL, serverClient, &error);
6684	if (!src)
6685		goto free_pixmap;
6686
6687	error = SetPictureTransform(src, &crtc->crtc_to_framebuffer);
6688	if (error)
6689		goto free_src;
6690
6691	if (crtc->filter && crtc->transform_in_use)
6692		SetPicturePictFilter(src, crtc->filter,
6693				     crtc->params, crtc->nparams);
6694
6695	dst = CreatePicture(None, &pixmap->drawable, format,
6696			    0, NULL, serverClient, &error);
6697	if (!dst)
6698		goto free_src;
6699
6700	kgem_bo_sync__gtt(&sna->kgem, bo);
6701
6702	if (sigtrap_get() == 0) { /* paranoia */
6703		const BoxRec *b = region_rects(region);
6704		int n = region_num_rects(region);
6705		do {
6706			BoxRec box;
6707
6708			box = *b++;
6709			transformed_box(&box, crtc);
6710
6711			DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n",
6712			     __FUNCTION__,
6713			     b[-1].x1, b[-1].y1, b[-1].x2-b[-1].x1, b[-1].y2-b[-1].y1,
6714			     box.x1, box.y1, box.x2, box.y2));
6715
6716			fbComposite(PictOpSrc, src, NULL, dst,
6717				    box.x1 + sx, box.y1 + sy,
6718				    0, 0,
6719				    box.x1, box.y1,
6720				    box.x2 - box.x1, box.y2 - box.y1);
6721		} while (--n);
6722		sigtrap_put();
6723	}
6724
6725	FreePicture(dst, None);
6726free_src:
6727	FreePicture(src, None);
6728free_pixmap:
6729	screen->DestroyPixmap(pixmap);
6730}
6731
6732static void
6733sna_crtc_redisplay__composite(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo)
6734{
6735	int16_t sx, sy;
6736	struct sna *sna = to_sna(crtc->scrn);
6737	ScreenPtr screen = crtc->scrn->pScreen;
6738	DrawablePtr draw = crtc_source(crtc, &sx, &sy);
6739	struct sna_composite_op tmp;
6740	PictFormatPtr format;
6741	PicturePtr src, dst;
6742	PixmapPtr pixmap;
6743	const BoxRec *b;
6744	int n, depth, error;
6745
6746	DBG(("%s: compositing transformed damage boxes\n", __FUNCTION__));
6747
6748	error = sna_render_format_for_depth(draw->depth);
6749	depth = PIXMAN_FORMAT_DEPTH(error);
6750	format = PictureMatchFormat(screen, depth, error);
6751	if (format == NULL) {
6752		DBG(("%s: can't find format for depth=%d [%08x]\n",
6753		     __FUNCTION__, depth, error));
6754		return;
6755	}
6756
6757	DBG(("%s: dst format=%08x, depth=%d, bpp=%d, pitch=%d, size=%dx%d\n",
6758	     __FUNCTION__, format->format, depth, draw->bitsPerPixel,
6759	     bo->pitch, crtc->mode.HDisplay, crtc->mode.VDisplay));
6760
6761	pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth);
6762	if (pixmap == NullPixmap)
6763		return;
6764
6765	if (!screen->ModifyPixmapHeader(pixmap,
6766					crtc->mode.HDisplay, crtc->mode.VDisplay,
6767					depth, draw->bitsPerPixel,
6768					bo->pitch, NULL))
6769		goto free_pixmap;
6770
6771	if (!sna_pixmap_attach_to_bo(pixmap, kgem_bo_reference(bo))) {
6772		kgem_bo_destroy(&sna->kgem, bo);
6773		goto free_pixmap;
6774	}
6775
6776	src = CreatePicture(None, draw, format,
6777			    0, NULL, serverClient, &error);
6778	if (!src)
6779		goto free_pixmap;
6780
6781	error = SetPictureTransform(src, &crtc->crtc_to_framebuffer);
6782	if (error)
6783		goto free_src;
6784
6785	if (crtc->filter && crtc->transform_in_use)
6786		SetPicturePictFilter(src, crtc->filter,
6787				     crtc->params, crtc->nparams);
6788
6789	dst = CreatePicture(None, &pixmap->drawable, format,
6790			    0, NULL, serverClient, &error);
6791	if (!dst)
6792		goto free_src;
6793
6794	ValidatePicture(src);
6795	ValidatePicture(dst);
6796
6797	if (!sna->render.composite(sna,
6798				   PictOpSrc, src, NULL, dst,
6799				   sx, sy,
6800				   0, 0,
6801				   0, 0,
6802				   crtc->mode.HDisplay, crtc->mode.VDisplay,
6803				   COMPOSITE_PARTIAL, memset(&tmp, 0, sizeof(tmp)))) {
6804		DBG(("%s: unsupported operation!\n", __FUNCTION__));
6805		sna_crtc_redisplay__fallback(crtc, region, bo);
6806		goto free_dst;
6807	}
6808
6809	n = region_num_rects(region);
6810	b = region_rects(region);
6811	do {
6812		BoxRec box;
6813
6814		box = *b++;
6815		transformed_box(&box, crtc);
6816
6817		DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n",
6818		     __FUNCTION__,
6819		     b[-1].x1, b[-1].y1, b[-1].x2-b[-1].x1, b[-1].y2-b[-1].y1,
6820		     box.x1, box.y1, box.x2, box.y2));
6821
6822		tmp.box(sna, &tmp, &box);
6823	} while (--n);
6824	tmp.done(sna, &tmp);
6825
6826free_dst:
6827	FreePicture(dst, None);
6828free_src:
6829	FreePicture(src, None);
6830free_pixmap:
6831	screen->DestroyPixmap(pixmap);
6832}
6833
6834static void
6835sna_crtc_redisplay(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo)
6836{
6837	int16_t tx, ty, sx, sy;
6838	struct sna *sna = to_sna(crtc->scrn);
6839	DrawablePtr draw = crtc_source(crtc, &sx, &sy);
6840	struct sna_pixmap *priv = sna_pixmap((PixmapPtr)draw);
6841
6842	DBG(("%s: crtc %d [pipe=%d], damage (%d, %d), (%d, %d) x %d\n",
6843	     __FUNCTION__, to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe,
6844	     region->extents.x1, region->extents.y1,
6845	     region->extents.x2, region->extents.y2,
6846	     region_num_rects(region)));
6847
6848	assert(!wedged(sna));
6849
6850	if (priv->clear) {
6851		RegionRec whole;
6852
6853		DBG(("%s: clear damage boxes\n", __FUNCTION__));
6854
6855		if (sna_transform_is_integer_translation(&crtc->crtc_to_framebuffer,
6856							 &tx, &ty)) {
6857			RegionTranslate(region, -tx, -ty);
6858		} else {
6859			whole.extents = region->extents;
6860			whole.data = NULL;
6861			transformed_box(&whole.extents, crtc);
6862			region = &whole;
6863		}
6864		if (sna_blt_fill_boxes(sna, GXcopy,
6865				       bo, draw->bitsPerPixel,
6866				       priv->clear_color,
6867				       region_rects(region),
6868				       region_num_rects(region)))
6869			return;
6870	}
6871
6872	if (crtc->filter == NULL &&
6873	    priv->gpu_bo &&
6874	    priv->cpu_damage == NULL &&
6875	    sna_transform_is_integer_translation(&crtc->crtc_to_framebuffer,
6876						 &tx, &ty)) {
6877		DrawableRec tmp;
6878
6879		DBG(("%s: copy damage boxes\n", __FUNCTION__));
6880
6881		tmp.width = crtc->mode.HDisplay;
6882		tmp.height = crtc->mode.VDisplay;
6883		tmp.depth = sna->front->drawable.depth;
6884		tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
6885
6886		if (sna->render.copy_boxes(sna, GXcopy,
6887					   draw, priv->gpu_bo, sx, sy,
6888					   &tmp, bo, -tx, -ty,
6889					   region_rects(region), region_num_rects(region), 0))
6890			return;
6891	}
6892
6893	if (can_render(sna))
6894		sna_crtc_redisplay__composite(crtc, region, bo);
6895	else
6896		sna_crtc_redisplay__fallback(crtc, region, bo);
6897}
6898
6899static void shadow_flip_handler(struct drm_event_vblank *e,
6900				void *data)
6901{
6902	sna_mode_redisplay(data);
6903}
6904
6905void sna_shadow_set_crtc(struct sna *sna,
6906			 xf86CrtcPtr crtc,
6907			 struct kgem_bo *bo)
6908{
6909	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
6910	struct sna_pixmap *priv;
6911
6912	DBG(("%s: setting shadow override for CRTC:%d to handle=%d\n",
6913	     __FUNCTION__, sna_crtc->id, bo->handle));
6914
6915	assert(sna->flags & SNA_TEAR_FREE);
6916	assert(sna_crtc);
6917	assert(!sna_crtc->transform);
6918
6919	if (sna_crtc->client_bo != bo) {
6920		if (sna_crtc->client_bo)
6921			kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo);
6922
6923		sna_crtc->client_bo = kgem_bo_reference(bo);
6924		sna_crtc_damage(crtc);
6925	}
6926
6927	list_move(&sna_crtc->shadow_link, &sna->mode.shadow_crtc);
6928	sna->mode.shadow_dirty = true;
6929
6930	priv = sna_pixmap(sna->front);
6931	assert(priv->gpu_bo);
6932	priv->move_to_gpu = wait_for_shadow;
6933	priv->move_to_gpu_data = sna;
6934}
6935
6936void sna_shadow_steal_crtcs(struct sna *sna, struct list *list)
6937{
6938	list_init(list);
6939	while (!list_is_empty(&sna->mode.shadow_crtc)) {
6940		RegionRec sub, *damage;
6941		struct sna_crtc *crtc =
6942			list_first_entry(&sna->mode.shadow_crtc,
6943					 struct sna_crtc,
6944					 shadow_link);
6945
6946		damage = DamageRegion(sna->mode.shadow_damage);
6947		sub.extents = crtc->base->bounds;
6948		sub.data = NULL;
6949		RegionSubtract(damage, damage, &sub);
6950
6951		list_move(&crtc->shadow_link, list);
6952	}
6953}
6954
6955void sna_shadow_unsteal_crtcs(struct sna *sna, struct list *list)
6956{
6957	while (!list_is_empty(list)) {
6958		struct sna_crtc *crtc =
6959			list_first_entry(list,
6960					 struct sna_crtc,
6961					 shadow_link);
6962		assert(crtc->client_bo);
6963		sna_shadow_set_crtc(sna, crtc->base, crtc->client_bo);
6964	}
6965}
6966
6967void sna_shadow_unset_crtc(struct sna *sna,
6968			   xf86CrtcPtr crtc)
6969{
6970	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
6971
6972	DBG(("%s: clearin shadow override for CRTC:%d\n",
6973	     __FUNCTION__, sna_crtc->id));
6974
6975	if (sna_crtc->client_bo == NULL)
6976		return;
6977
6978	kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo);
6979	sna_crtc->client_bo = NULL;
6980	list_del(&sna_crtc->shadow_link);
6981	sna->mode.shadow_dirty = true;
6982
6983	sna_crtc_damage(crtc);
6984}
6985
6986void sna_mode_redisplay(struct sna *sna)
6987{
6988	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
6989	RegionPtr region;
6990	int i;
6991
6992	if (!sna->mode.shadow_damage)
6993		return;
6994
6995	DBG(("%s: posting shadow damage? %d (flips pending? %d, mode reconfiguration pending? %d)\n",
6996	     __FUNCTION__,
6997	     !RegionNil(DamageRegion(sna->mode.shadow_damage)),
6998	     sna->mode.flip_active,
6999	     sna->mode.dirty));
7000	assert((sna->flags & SNA_IS_HOSTED) == 0);
7001	assert(sna->mode.shadow_active);
7002
7003	if (sna->mode.dirty)
7004		return;
7005
7006	region = DamageRegion(sna->mode.shadow_damage);
7007	if (RegionNil(region))
7008		return;
7009
7010	DBG(("%s: damage: %dx(%d, %d), (%d, %d)\n",
7011	     __FUNCTION__, region_num_rects(region),
7012	     region->extents.x1, region->extents.y1,
7013	     region->extents.x2, region->extents.y2));
7014
7015	if (sna->mode.flip_active) {
7016		DamagePtr damage;
7017
7018		damage = sna->mode.shadow_damage;
7019		sna->mode.shadow_damage = NULL;
7020
7021		while (sna->mode.flip_active && sna_mode_wakeup(sna))
7022			;
7023
7024		sna->mode.shadow_damage = damage;
7025	}
7026
7027	if (sna->mode.flip_active)
7028		return;
7029
7030	if (wedged(sna) || !sna_pixmap_move_to_gpu(sna->front, MOVE_READ | MOVE_ASYNC_HINT | __MOVE_SCANOUT)) {
7031		DBG(("%s: forcing scanout update using the CPU\n", __FUNCTION__));
7032		if (!sna_pixmap_move_to_cpu(sna->front, MOVE_READ))
7033			return;
7034
7035		for (i = 0; i < sna->mode.num_real_crtc; i++) {
7036			xf86CrtcPtr crtc = config->crtc[i];
7037			struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
7038			RegionRec damage;
7039
7040			assert(sna_crtc != NULL);
7041			if (!sna_crtc->shadow)
7042				continue;
7043
7044			assert(crtc->enabled);
7045			assert(sna_crtc->transform || sna->flags & SNA_TEAR_FREE);
7046
7047			damage.extents = crtc->bounds;
7048			damage.data = NULL;
7049			RegionIntersect(&damage, &damage, region);
7050			if (!box_empty(&damage.extents)) {
7051				struct kgem_bo *bo = NULL;
7052
7053				DBG(("%s: fallback intersects pipe=%d [(%d, %d), (%d, %d)]\n",
7054				     __FUNCTION__, sna_crtc->pipe,
7055				     damage.extents.x1, damage.extents.y1,
7056				     damage.extents.x2, damage.extents.y2));
7057
7058				if (sna->flags & SNA_TEAR_FREE) {
7059					RegionRec new_damage;
7060
7061					RegionNull(&new_damage);
7062					RegionCopy(&new_damage, &damage);
7063
7064					bo = sna_crtc->client_bo;
7065					if (bo == NULL) {
7066						damage.extents = crtc->bounds;
7067						damage.data = NULL;
7068						bo = kgem_create_2d(&sna->kgem,
7069								crtc->mode.HDisplay,
7070								crtc->mode.VDisplay,
7071								crtc->scrn->bitsPerPixel,
7072								sna_crtc->bo->tiling,
7073								CREATE_SCANOUT);
7074					} else
7075						RegionUnion(&damage, &damage, &sna_crtc->client_damage);
7076
7077					DBG(("%s: TearFree fallback, shadow handle=%d, crtc handle=%d\n", __FUNCTION__, bo->handle, sna_crtc->bo->handle));
7078
7079					sna_crtc->client_damage = new_damage;
7080				}
7081
7082				if (bo == NULL)
7083					bo = sna_crtc->bo;
7084				sna_crtc_redisplay__fallback(crtc, &damage, bo);
7085
7086				if (bo != sna_crtc->bo) {
7087					struct drm_mode_crtc_page_flip arg;
7088
7089					arg.crtc_id = sna_crtc->id;
7090					arg.fb_id = get_fb(sna, bo,
7091							   crtc->mode.HDisplay,
7092							   crtc->mode.VDisplay);
7093
7094					arg.user_data = (uintptr_t)sna_crtc;
7095					arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
7096					arg.reserved = 0;
7097
7098					if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
7099						if (sna_crtc_flip(sna, sna_crtc, bo, 0, 0)) {
7100							assert(sna_crtc->bo->active_scanout);
7101							assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout);
7102							sna_crtc->bo->active_scanout--;
7103							kgem_bo_destroy(&sna->kgem, sna_crtc->bo);
7104
7105							sna_crtc->bo = bo;
7106							sna_crtc->bo->active_scanout++;
7107							sna_crtc->client_bo = NULL;
7108						} else {
7109							DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n",
7110							     __FUNCTION__, arg.fb_id, i, sna_crtc->id, sna_crtc->pipe, errno));
7111							xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
7112								   "Page flipping failed, disabling TearFree\n");
7113							sna->flags &= ~SNA_TEAR_FREE;
7114
7115							damage.extents = crtc->bounds;
7116							damage.data = NULL;
7117							sna_crtc_redisplay__fallback(crtc, &damage, sna_crtc->bo);
7118
7119							kgem_bo_destroy(&sna->kgem, bo);
7120							sna_crtc->client_bo = NULL;
7121						}
7122					} else {
7123						sna->mode.flip_active++;
7124
7125						assert(sna_crtc->flip_bo == NULL);
7126						sna_crtc->flip_handler = shadow_flip_handler;
7127						sna_crtc->flip_data = sna;
7128						sna_crtc->flip_bo = bo;
7129						sna_crtc->flip_bo->active_scanout++;
7130						sna_crtc->flip_serial = sna_crtc->mode_serial;
7131
7132						sna_crtc->client_bo = kgem_bo_reference(sna_crtc->bo);
7133					}
7134				}
7135			}
7136			RegionUninit(&damage);
7137
7138			if (sna_crtc->slave_damage)
7139				DamageEmpty(sna_crtc->slave_damage);
7140		}
7141
7142		RegionEmpty(region);
7143		return;
7144	}
7145
7146	{
7147		struct sna_pixmap *priv;
7148
7149		priv = sna_pixmap(sna->front);
7150		assert(priv != NULL);
7151
7152		if (priv->move_to_gpu) {
7153			if (priv->move_to_gpu == wait_for_shadow &&
7154			    !sna->mode.shadow_dirty) {
7155				/* No damage written to new scanout
7156				 * (backbuffer), ignore redisplay request
7157				 * and continue with the current intact
7158				 * scanout (frontbuffer).
7159				 */
7160				DBG(("%s: shadow idle, skipping update\n", __FUNCTION__));
7161				RegionEmpty(region);
7162				return;
7163			}
7164
7165			(void)priv->move_to_gpu(sna, priv, 0);
7166		}
7167
7168		assert(priv->move_to_gpu == NULL);
7169	}
7170
7171	for (i = 0; i < sna->mode.num_real_crtc; i++) {
7172		xf86CrtcPtr crtc = config->crtc[i];
7173		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
7174		RegionRec damage;
7175
7176		assert(sna_crtc != NULL);
7177		DBG(("%s: crtc[%d] transformed? %d\n",
7178		     __FUNCTION__, i, sna_crtc->transform));
7179
7180		if (!sna_crtc->transform)
7181			continue;
7182
7183		assert(crtc->enabled);
7184		assert(sna_crtc->bo);
7185
7186		damage.extents = crtc->bounds;
7187		damage.data = NULL;
7188
7189		RegionIntersect(&damage, &damage, region);
7190		DBG(("%s: crtc[%d] damage? %d[%d]: %dx[(%d, %d), (%d, %d)]\n",
7191		     __FUNCTION__, i,
7192		     !box_empty(&damage.extents), RegionNotEmpty(&damage),
7193		     region_num_rects(&damage),
7194		     damage.extents.x1, damage.extents.y1,
7195		     damage.extents.x2, damage.extents.y2));
7196		if (!box_empty(&damage.extents)) {
7197			if (sna->flags & SNA_TEAR_FREE) {
7198				struct drm_mode_crtc_page_flip arg;
7199				struct kgem_bo *bo;
7200
7201				RegionUninit(&damage);
7202				damage.extents = crtc->bounds;
7203				damage.data = NULL;
7204
7205				bo = sna_crtc->client_bo;
7206				if (bo == NULL)
7207					bo = kgem_create_2d(&sna->kgem,
7208							    crtc->mode.HDisplay,
7209							    crtc->mode.VDisplay,
7210							    crtc->scrn->bitsPerPixel,
7211							    sna_crtc->bo->tiling,
7212							    CREATE_SCANOUT);
7213				if (bo == NULL)
7214					goto disable1;
7215
7216				sna_crtc_redisplay(crtc, &damage, bo);
7217				kgem_bo_submit(&sna->kgem, bo);
7218
7219				arg.crtc_id = sna_crtc->id;
7220				arg.fb_id = get_fb(sna, bo,
7221						   crtc->mode.HDisplay,
7222						   crtc->mode.VDisplay);
7223				if (arg.fb_id == 0)
7224					goto disable1;
7225
7226				arg.user_data = (uintptr_t)sna_crtc;
7227				arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
7228				arg.reserved = 0;
7229
7230				if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
7231					if (sna_crtc_flip(sna, sna_crtc, bo, 0, 0)) {
7232						assert(sna_crtc->bo->active_scanout);
7233						assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout);
7234						sna_crtc->bo->active_scanout--;
7235						kgem_bo_destroy(&sna->kgem, sna_crtc->bo);
7236
7237						sna_crtc->bo = kgem_bo_reference(bo);
7238						sna_crtc->bo->active_scanout++;
7239						sna_crtc->client_bo = kgem_bo_reference(bo);
7240					} else {
7241						BoxRec box;
7242						DrawableRec tmp;
7243
7244						DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n",
7245						     __FUNCTION__, arg.fb_id, i, sna_crtc->id, sna_crtc->pipe, errno));
7246						xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
7247							   "Page flipping failed, disabling TearFree\n");
7248						sna->flags &= ~SNA_TEAR_FREE;
7249
7250disable1:
7251						box.x1 = 0;
7252						box.y1 = 0;
7253						tmp.width = box.x2 = crtc->mode.HDisplay;
7254						tmp.height = box.y2 = crtc->mode.VDisplay;
7255						tmp.depth = sna->front->drawable.depth;
7256						tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
7257
7258						if (!sna->render.copy_boxes(sna, GXcopy,
7259									    &sna->front->drawable, bo, 0, 0,
7260									    &tmp, sna_crtc->bo, 0, 0,
7261									    &box, 1, COPY_LAST)) {
7262							xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
7263								   "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n",
7264								   __FUNCTION__, sna_crtc->id, sna_crtc->pipe);
7265							sna_crtc_disable(crtc);
7266						}
7267
7268						kgem_bo_destroy(&sna->kgem, bo);
7269						sna_crtc->client_bo = NULL;
7270					}
7271					continue;
7272				}
7273				sna->mode.flip_active++;
7274
7275				assert(sna_crtc->flip_bo == NULL);
7276				sna_crtc->flip_handler = shadow_flip_handler;
7277				sna_crtc->flip_data = sna;
7278				sna_crtc->flip_bo = bo;
7279				sna_crtc->flip_bo->active_scanout++;
7280				sna_crtc->flip_serial = sna_crtc->mode_serial;
7281				sna_crtc->flip_pending = true;
7282
7283				sna_crtc->client_bo = kgem_bo_reference(sna_crtc->bo);
7284			} else {
7285				sna_crtc_redisplay(crtc, &damage, sna_crtc->bo);
7286				kgem_scanout_flush(&sna->kgem, sna_crtc->bo);
7287			}
7288		}
7289		RegionUninit(&damage);
7290
7291		if (sna_crtc->slave_damage)
7292			DamageEmpty(sna_crtc->slave_damage);
7293	}
7294
7295	if (sna->mode.shadow) {
7296		struct kgem_bo *new = __sna_pixmap_get_bo(sna->front);
7297		struct kgem_bo *old = sna->mode.shadow;
7298		struct drm_mode_crtc_page_flip arg;
7299		uint32_t fb = 0;
7300
7301		DBG(("%s: flipping TearFree outputs, current scanout handle=%d [active?=%d], new handle=%d [active=%d]\n",
7302		     __FUNCTION__, old->handle, old->active_scanout, new->handle, new->active_scanout));
7303
7304		assert(new != old);
7305		assert(new->refcnt);
7306
7307		arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
7308		arg.reserved = 0;
7309
7310		kgem_bo_submit(&sna->kgem, new);
7311
7312		for (i = 0; i < sna->mode.num_real_crtc; i++) {
7313			struct sna_crtc *crtc = config->crtc[i]->driver_private;
7314			struct kgem_bo *flip_bo;
7315			int x, y;
7316
7317			assert(crtc != NULL);
7318			DBG(("%s: crtc %d [%d, pipe=%d] active? %d, transformed? %d\n",
7319			     __FUNCTION__, i, crtc->id, crtc->pipe, crtc->bo ? crtc->bo->handle : 0, crtc->transform));
7320			if (crtc->bo == NULL || crtc->transform)
7321				continue;
7322
7323			assert(config->crtc[i]->enabled);
7324			assert(crtc->dpms_mode <= DPMSModeOn);
7325			assert(crtc->flip_bo == NULL);
7326
7327			arg.crtc_id = crtc->id;
7328			arg.user_data = (uintptr_t)crtc;
7329
7330			if (crtc->client_bo) {
7331				DBG(("%s: apply shadow override bo for CRTC:%d on pipe=%d, handle=%d\n",
7332				     __FUNCTION__, crtc->id, crtc->pipe, crtc->client_bo->handle));
7333				arg.fb_id = get_fb(sna, crtc->client_bo,
7334						   crtc->base->mode.HDisplay,
7335						   crtc->base->mode.VDisplay);
7336				assert(arg.fb_id != fb);
7337				flip_bo = crtc->client_bo;
7338				x = y = 0;
7339			} else {
7340				if (fb == 0)
7341					fb = get_fb(sna, new, sna->scrn->virtualX, sna->scrn->virtualY);
7342				if (fb == 0) {
7343fixup_shadow:
7344					if (sna_pixmap_move_to_gpu(sna->front, MOVE_READ | MOVE_ASYNC_HINT)) {
7345						BoxRec box;
7346
7347						box.x1 = 0;
7348						box.y1 = 0;
7349						box.x2 = sna->scrn->virtualX;
7350						box.y2 = sna->scrn->virtualY;
7351						if (sna->render.copy_boxes(sna, GXcopy,
7352									   &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0,
7353									   &sna->front->drawable, old, 0, 0,
7354									   &box, 1, COPY_LAST)) {
7355							kgem_submit(&sna->kgem);
7356							RegionEmpty(region);
7357						}
7358					}
7359
7360					return;
7361				}
7362
7363				arg.fb_id = fb;
7364				flip_bo = new;
7365				x = crtc->base->x;
7366				y = crtc->base->y;
7367			}
7368
7369			if (crtc->bo == flip_bo)
7370				continue;
7371
7372			if (flip_bo->pitch != crtc->bo->pitch || (y << 16 | x)  != crtc->offset) {
7373				DBG(("%s: changing pitch (new %d =?= old %d) or offset (new %x =?= old %x)\n",
7374				     __FUNCTION__,
7375				     flip_bo->pitch, crtc->bo->pitch,
7376				     y << 16 | x, crtc->offset));
7377fixup_flip:
7378				if (sna_crtc_flip(sna, crtc, flip_bo, x, y)) {
7379					assert(flip_bo != crtc->bo);
7380					assert(crtc->bo->active_scanout);
7381					assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
7382					crtc->bo->active_scanout--;
7383					kgem_bo_destroy(&sna->kgem, crtc->bo);
7384
7385					if (crtc->shadow_bo) {
7386						kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
7387						crtc->shadow_bo = NULL;
7388					}
7389
7390					crtc->bo = kgem_bo_reference(flip_bo);
7391					crtc->bo->active_scanout++;
7392				} else {
7393					xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
7394						   "Failed to prepare CRTC for page flipping, disabling TearFree\n");
7395					sna->flags &= ~SNA_TEAR_FREE;
7396
7397					if (sna->mode.flip_active == 0) {
7398						DBG(("%s: abandoning flip attempt\n", __FUNCTION__));
7399						goto fixup_shadow;
7400					}
7401
7402					xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
7403						   "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n",
7404						   __FUNCTION__, crtc->id, crtc->pipe);
7405					sna_crtc_disable(crtc->base);
7406				}
7407				continue;
7408			}
7409
7410			if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
7411				ERR(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n",
7412				     __FUNCTION__, arg.fb_id, i, crtc->id, crtc->pipe, errno));
7413				goto fixup_flip;
7414			}
7415			sna->mode.flip_active++;
7416
7417			assert(crtc->flip_bo == NULL);
7418			crtc->flip_handler = shadow_flip_handler;
7419			crtc->flip_data = sna;
7420			crtc->flip_bo = kgem_bo_reference(flip_bo);
7421			crtc->flip_bo->active_scanout++;
7422			crtc->flip_serial = crtc->mode_serial;
7423			crtc->flip_pending = true;
7424
7425			{
7426				struct drm_i915_gem_busy busy = { flip_bo->handle };
7427				if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_BUSY, &busy) == 0) {
7428					if (busy.busy) {
7429						int mode = KGEM_RENDER;
7430						if (busy.busy & (0xfffe << 16))
7431							mode = KGEM_BLT;
7432						DBG(("%s: marking flip bo as busy [%x -> mode=%d]\n", __FUNCTION__, busy.busy, mode));
7433						kgem_bo_mark_busy(&sna->kgem, flip_bo, mode);
7434					} else
7435						__kgem_bo_clear_busy(flip_bo);
7436				}
7437			}
7438		}
7439
7440		DBG(("%s: flipped %d outputs, shadow active? %d\n",
7441		     __FUNCTION__,
7442		     sna->mode.flip_active,
7443		     sna->mode.shadow ? sna->mode.shadow->handle : 0));
7444
7445		if (sna->mode.flip_active) {
7446			assert(old == sna->mode.shadow);
7447			assert(old->refcnt >= 1);
7448			set_shadow(sna, region);
7449		}
7450	} else
7451		kgem_submit(&sna->kgem);
7452
7453	RegionEmpty(region);
7454}
7455
7456int sna_mode_wakeup(struct sna *sna)
7457{
7458	char buffer[1024];
7459	int len, i;
7460	int ret = 0;
7461
7462again:
7463	/* In order to workaround a kernel bug in not honouring O_NONBLOCK,
7464	 * check that the fd is readable before attempting to read the next
7465	 * event from drm.
7466	 */
7467	if (!event_pending(sna->kgem.fd))
7468		return ret;
7469
7470	/* The DRM read semantics guarantees that we always get only
7471	 * complete events.
7472	 */
7473	len = read(sna->kgem.fd, buffer, sizeof (buffer));
7474	if (len < (int)sizeof(struct drm_event))
7475		return ret;
7476
7477	/* Note that we cannot rely on the passed in struct sna matching
7478	 * the struct sna used for the vblank event (in case it was submitted
7479	 * by a different ZaphodHead). When processing the event, we must
7480	 * ensure that we only use the pointer passed along with the event.
7481	 */
7482
7483	DBG(("%s: len=%d\n", __FUNCTION__, len));
7484
7485	i = 0;
7486	while (i < len) {
7487		struct drm_event *e = (struct drm_event *)&buffer[i];
7488		switch (e->type) {
7489		case DRM_EVENT_VBLANK:
7490			if (((uintptr_t)((struct drm_event_vblank *)e)->user_data) & 2)
7491				sna_present_vblank_handler((struct drm_event_vblank *)e);
7492			else
7493				sna_dri2_vblank_handler((struct drm_event_vblank *)e);
7494			break;
7495		case DRM_EVENT_FLIP_COMPLETE:
7496			{
7497				struct drm_event_vblank *vbl = (struct drm_event_vblank *)e;
7498				struct sna_crtc *crtc = (void *)(uintptr_t)vbl->user_data;
7499
7500				/* Beware Zaphod! */
7501				sna = to_sna(crtc->base->scrn);
7502
7503				crtc->swap.tv_sec = vbl->tv_sec;
7504				crtc->swap.tv_usec = vbl->tv_usec;
7505				crtc->swap.msc = msc64(crtc, vbl->sequence);
7506				crtc->flip_pending = false;
7507
7508				assert(crtc->flip_bo);
7509				assert(crtc->flip_bo->active_scanout);
7510				assert(crtc->flip_bo->refcnt >= crtc->flip_bo->active_scanout);
7511
7512				if (crtc->flip_serial == crtc->mode_serial) {
7513					DBG(("%s: removing handle=%d from scanout, installing handle=%d\n",
7514					     __FUNCTION__, crtc->bo->handle, crtc->flip_bo->handle));
7515					assert(crtc->bo->active_scanout);
7516					assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
7517					crtc->bo->active_scanout--;
7518					kgem_bo_destroy(&sna->kgem, crtc->bo);
7519
7520					if (crtc->shadow_bo) {
7521						kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
7522						crtc->shadow_bo = NULL;
7523					}
7524
7525					crtc->bo = crtc->flip_bo;
7526					crtc->flip_bo = NULL;
7527				} else {
7528					crtc->flip_bo->active_scanout--;
7529					kgem_bo_destroy(&sna->kgem, crtc->flip_bo);
7530					crtc->flip_bo = NULL;
7531				}
7532
7533				DBG(("%s: flip complete, pending? %d\n", __FUNCTION__, sna->mode.flip_active));
7534				assert(sna->mode.flip_active);
7535				if (--sna->mode.flip_active == 0)
7536					crtc->flip_handler(vbl, crtc->flip_data);
7537			}
7538			break;
7539		default:
7540			break;
7541		}
7542		i += e->length;
7543		ret++;
7544	}
7545
7546	goto again;
7547}
7548