drmmode_display.c revision 3ed65abb
1/*
2 * Copyright © 2007 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 *    Dave Airlie <airlied@redhat.com>
25 *
26 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <errno.h>
33#include <sys/ioctl.h>
34#include <time.h>
35#include "cursorstr.h"
36#include "damagestr.h"
37#include "micmap.h"
38#include "xf86cmap.h"
39#include "xf86Priv.h"
40#include "radeon.h"
41#include "radeon_bo_helper.h"
42#include "radeon_glamor.h"
43#include "radeon_list.h"
44#include "radeon_reg.h"
45
46#ifdef RADEON_PIXMAP_SHARING
47#include <dri.h>
48#endif
49
50#include "drmmode_display.h"
51
52/* DPMS */
53#ifdef HAVE_XEXTPROTO_71
54#include <X11/extensions/dpmsconst.h>
55#else
56#define DPMS_SERVER
57#include <X11/extensions/dpms.h>
58#endif
59
60#define DEFAULT_NOMINAL_FRAME_RATE 60
61
62#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 22
63#define HAVE_NOTIFY_FD	1
64#endif
65
66static Bool
67drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height);
68
69static Bool
70RADEONZaphodStringMatches(ScrnInfoPtr pScrn, const char *s, char *output_name)
71{
72    int i = 0;
73    char s1[20];
74
75    do {
76	switch(*s) {
77	case ',':
78  	    s1[i] = '\0';
79	    i = 0;
80	    if (strcmp(s1, output_name) == 0)
81		return TRUE;
82	    break;
83	case ' ':
84	case '\t':
85	case '\n':
86	case '\r':
87	    break;
88	default:
89	    s1[i] = *s;
90	    i++;
91	    break;
92	}
93    } while(*s++);
94
95    s1[i] = '\0';
96    if (strcmp(s1, output_name) == 0)
97	return TRUE;
98
99    return FALSE;
100}
101
102static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn,
103					  int width, int height,
104					  int depth, int bpp,
105					  int pitch,
106					  struct radeon_bo *bo, struct radeon_surface *psurf)
107{
108	RADEONInfoPtr info = RADEONPTR(pScrn);
109	ScreenPtr pScreen = pScrn->pScreen;
110	PixmapPtr pixmap;
111	struct radeon_surface *surface;
112	uint32_t tiling;
113
114	pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth,
115					  RADEON_CREATE_PIXMAP_SCANOUT);
116	if (!pixmap)
117		return NULL;
118
119	if (!(*pScreen->ModifyPixmapHeader)(pixmap, width, height,
120					    depth, bpp, pitch, NULL)) {
121		goto fail;
122	}
123
124	if (!info->use_glamor)
125		exaMoveInPixmap(pixmap);
126
127	if (!radeon_set_pixmap_bo(pixmap, bo))
128		goto fail;
129
130	if (info->ChipFamily >= CHIP_FAMILY_R600) {
131		surface = radeon_get_pixmap_surface(pixmap);
132		if (surface && psurf)
133			*surface = *psurf;
134		else if (surface) {
135			memset(surface, 0, sizeof(struct radeon_surface));
136			surface->npix_x = width;
137			surface->npix_y = height;
138			surface->npix_z = 1;
139			surface->blk_w = 1;
140			surface->blk_h = 1;
141			surface->blk_d = 1;
142			surface->array_size = 1;
143			surface->last_level = 0;
144			surface->bpe = bpp / 8;
145			surface->nsamples = 1;
146			surface->flags = RADEON_SURF_SCANOUT;
147			/* we are requiring a recent enough libdrm version */
148			surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
149			surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
150			surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
151			tiling = radeon_get_pixmap_tiling_flags(pixmap);
152			if (tiling & RADEON_TILING_MICRO) {
153				surface->flags = RADEON_SURF_CLR(surface->flags, MODE);
154				surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
155			}
156			if (tiling & RADEON_TILING_MACRO) {
157				surface->flags = RADEON_SURF_CLR(surface->flags, MODE);
158				surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
159			}
160			if (radeon_surface_best(info->surf_man, surface)) {
161				goto fail;
162			}
163			if (radeon_surface_init(info->surf_man, surface)) {
164				goto fail;
165			}
166		}
167	}
168
169	if (!info->use_glamor ||
170	    radeon_glamor_create_textured_pixmap(pixmap,
171						 radeon_get_pixmap_private(pixmap)))
172		return pixmap;
173
174fail:
175	pScreen->DestroyPixmap(pixmap);
176	return NULL;
177}
178
179static void drmmode_destroy_bo_pixmap(PixmapPtr pixmap)
180{
181	ScreenPtr pScreen = pixmap->drawable.pScreen;
182
183	(*pScreen->DestroyPixmap)(pixmap);
184}
185
186static void
187drmmode_ConvertFromKMode(ScrnInfoPtr	scrn,
188		     drmModeModeInfo *kmode,
189		     DisplayModePtr	mode)
190{
191	memset(mode, 0, sizeof(DisplayModeRec));
192	mode->status = MODE_OK;
193
194	mode->Clock = kmode->clock;
195
196	mode->HDisplay = kmode->hdisplay;
197	mode->HSyncStart = kmode->hsync_start;
198	mode->HSyncEnd = kmode->hsync_end;
199	mode->HTotal = kmode->htotal;
200	mode->HSkew = kmode->hskew;
201
202	mode->VDisplay = kmode->vdisplay;
203	mode->VSyncStart = kmode->vsync_start;
204	mode->VSyncEnd = kmode->vsync_end;
205	mode->VTotal = kmode->vtotal;
206	mode->VScan = kmode->vscan;
207
208	mode->Flags = kmode->flags; //& FLAG_BITS;
209	mode->name = strdup(kmode->name);
210
211	if (kmode->type & DRM_MODE_TYPE_DRIVER)
212		mode->type = M_T_DRIVER;
213	if (kmode->type & DRM_MODE_TYPE_PREFERRED)
214		mode->type |= M_T_PREFERRED;
215	xf86SetModeCrtc (mode, scrn->adjustFlags);
216}
217
218static void
219drmmode_ConvertToKMode(ScrnInfoPtr	scrn,
220		     drmModeModeInfo *kmode,
221		     DisplayModePtr	mode)
222{
223	memset(kmode, 0, sizeof(*kmode));
224
225	kmode->clock = mode->Clock;
226	kmode->hdisplay = mode->HDisplay;
227	kmode->hsync_start = mode->HSyncStart;
228	kmode->hsync_end = mode->HSyncEnd;
229	kmode->htotal = mode->HTotal;
230	kmode->hskew = mode->HSkew;
231
232	kmode->vdisplay = mode->VDisplay;
233	kmode->vsync_start = mode->VSyncStart;
234	kmode->vsync_end = mode->VSyncEnd;
235	kmode->vtotal = mode->VTotal;
236	kmode->vscan = mode->VScan;
237
238	kmode->flags = mode->Flags; //& FLAG_BITS;
239	if (mode->name)
240		strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
241	kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
242
243}
244
245/*
246 * Retrieves present time in microseconds that is compatible
247 * with units used by vblank timestamps. Depending on the kernel
248 * version and DRM kernel module configuration, the vblank
249 * timestamp can either be in real time or monotonic time
250 */
251int drmmode_get_current_ust(int drm_fd, CARD64 *ust)
252{
253	uint64_t cap_value;
254	int ret;
255	struct timespec now;
256
257	ret = drmGetCap(drm_fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap_value);
258	if (ret || !cap_value)
259		/* old kernel or drm_timestamp_monotonic turned off */
260		ret = clock_gettime(CLOCK_REALTIME, &now);
261	else
262		ret = clock_gettime(CLOCK_MONOTONIC, &now);
263	if (ret)
264		return ret;
265	*ust = ((CARD64)now.tv_sec * 1000000) + ((CARD64)now.tv_nsec / 1000);
266	return 0;
267}
268
269/*
270 * Get current frame count and frame count timestamp of the crtc.
271 */
272int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc)
273{
274    ScrnInfoPtr scrn = crtc->scrn;
275    RADEONInfoPtr info = RADEONPTR(scrn);
276    drmVBlank vbl;
277    int ret;
278
279    vbl.request.type = DRM_VBLANK_RELATIVE;
280    vbl.request.type |= radeon_populate_vbl_request_type(crtc);
281    vbl.request.sequence = 0;
282
283    ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
284    if (ret) {
285	xf86DrvMsg(scrn->scrnIndex, X_WARNING,
286		   "get vblank counter failed: %s\n", strerror(errno));
287	return ret;
288    }
289
290    *ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec;
291    *msc = vbl.reply.sequence;
292
293    return Success;
294}
295
296static void
297drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode)
298{
299	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
300	ScrnInfoPtr scrn = crtc->scrn;
301	RADEONInfoPtr info = RADEONPTR(scrn);
302	CARD64 ust;
303	int ret;
304
305	drmmode_crtc->pending_dpms_mode = mode;
306
307	if (drmmode_crtc->dpms_mode == DPMSModeOn && mode != DPMSModeOn) {
308		drmVBlank vbl;
309
310		/* Wait for any pending flip to finish */
311		if (drmmode_crtc->flip_pending)
312			return;
313
314		/*
315		 * On->Off transition: record the last vblank time,
316		 * sequence number and frame period.
317		 */
318		vbl.request.type = DRM_VBLANK_RELATIVE;
319		vbl.request.type |= radeon_populate_vbl_request_type(crtc);
320		vbl.request.sequence = 0;
321		ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
322		if (ret)
323			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
324				   "%s cannot get last vblank counter\n",
325				   __func__);
326		else {
327			CARD64 seq = (CARD64)vbl.reply.sequence;
328			CARD64 nominal_frame_rate, pix_in_frame;
329
330			ust = ((CARD64)vbl.reply.tval_sec * 1000000) +
331				vbl.reply.tval_usec;
332			drmmode_crtc->dpms_last_ust = ust;
333			drmmode_crtc->dpms_last_seq = seq;
334			nominal_frame_rate = crtc->mode.Clock;
335			nominal_frame_rate *= 1000;
336			pix_in_frame = crtc->mode.HTotal * crtc->mode.VTotal;
337			if (nominal_frame_rate == 0 || pix_in_frame == 0)
338				nominal_frame_rate = DEFAULT_NOMINAL_FRAME_RATE;
339			else
340				nominal_frame_rate /= pix_in_frame;
341			drmmode_crtc->dpms_last_fps = nominal_frame_rate;
342		}
343	} else if (drmmode_crtc->dpms_mode != DPMSModeOn && mode == DPMSModeOn) {
344		/*
345		 * Off->On transition: calculate and accumulate the
346		 * number of interpolated vblanks while we were in Off state
347		 */
348		ret = drmmode_get_current_ust(info->dri2.drm_fd, &ust);
349		if (ret)
350			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
351				   "%s cannot get current time\n", __func__);
352		else if (drmmode_crtc->dpms_last_ust) {
353			CARD64 time_elapsed, delta_seq;
354			time_elapsed = ust - drmmode_crtc->dpms_last_ust;
355			delta_seq = time_elapsed * drmmode_crtc->dpms_last_fps;
356			delta_seq /= 1000000;
357			drmmode_crtc->interpolated_vblanks += delta_seq;
358
359		}
360	}
361	drmmode_crtc->dpms_mode = mode;
362}
363
364static void
365drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
366{
367	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
368	drmmode_ptr drmmode = drmmode_crtc->drmmode;
369
370	/* Disable unused CRTCs */
371	if (!crtc->enabled || mode != DPMSModeOn) {
372		/* Wait for any pending flip to finish */
373		if (drmmode_crtc->flip_pending)
374			return;
375
376		drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
377			       0, 0, 0, NULL, 0, NULL);
378	} else if (drmmode_crtc->dpms_mode != DPMSModeOn)
379		crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation,
380					    crtc->x, crtc->y);
381}
382
383static PixmapPtr
384create_pixmap_for_fbcon(drmmode_ptr drmmode,
385			ScrnInfoPtr pScrn, int fbcon_id)
386{
387	RADEONInfoPtr info = RADEONPTR(pScrn);
388	PixmapPtr pixmap = info->fbcon_pixmap;
389	struct radeon_bo *bo;
390	drmModeFBPtr fbcon;
391	struct drm_gem_flink flink;
392
393	if (pixmap)
394	    return pixmap;
395
396	fbcon = drmModeGetFB(drmmode->fd, fbcon_id);
397	if (fbcon == NULL)
398		return NULL;
399
400	if (fbcon->depth != pScrn->depth ||
401	    fbcon->width != pScrn->virtualX ||
402	    fbcon->height != pScrn->virtualY)
403		goto out_free_fb;
404
405	flink.handle = fbcon->handle;
406	if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
407		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
408			   "Couldn't flink fbcon handle\n");
409		goto out_free_fb;
410	}
411
412	bo = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0);
413	if (bo == NULL) {
414		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
415			   "Couldn't allocate bo for fbcon handle\n");
416		goto out_free_fb;
417	}
418
419	pixmap = drmmode_create_bo_pixmap(pScrn, fbcon->width, fbcon->height,
420					  fbcon->depth, fbcon->bpp, fbcon->pitch,
421					  bo, NULL);
422	info->fbcon_pixmap = pixmap;
423	radeon_bo_unref(bo);
424out_free_fb:
425	drmModeFreeFB(fbcon);
426	return pixmap;
427}
428
429static void
430destroy_pixmap_for_fbcon(ScrnInfoPtr pScrn)
431{
432	RADEONInfoPtr info = RADEONPTR(pScrn);
433
434	/* XXX: The current GPUVM support in the kernel doesn't allow removing
435	 * the virtual address range for this BO, so we need to keep around
436	 * the pixmap to avoid breaking glamor with GPUVM
437	 */
438	if (info->use_glamor && info->ChipFamily >= CHIP_FAMILY_CAYMAN)
439		return;
440
441	if (info->fbcon_pixmap)
442		pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap);
443	info->fbcon_pixmap = NULL;
444}
445
446void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
447{
448	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
449	RADEONInfoPtr info = RADEONPTR(pScrn);
450	PixmapPtr src, dst;
451	ScreenPtr pScreen = pScrn->pScreen;
452	int fbcon_id = 0;
453	Bool force;
454	GCPtr gc;
455	int i;
456
457	for (i = 0; i < xf86_config->num_crtc; i++) {
458		drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[i]->driver_private;
459
460		if (drmmode_crtc->mode_crtc->buffer_id)
461			fbcon_id = drmmode_crtc->mode_crtc->buffer_id;
462	}
463
464	if (!fbcon_id)
465		return;
466
467	if (fbcon_id == drmmode->fb_id) {
468		/* in some rare case there might be no fbcon and we might already
469		 * be the one with the current fb to avoid a false deadlck in
470		 * kernel ttm code just do nothing as anyway there is nothing
471		 * to do
472		 */
473		return;
474	}
475
476	src = create_pixmap_for_fbcon(drmmode, pScrn, fbcon_id);
477	if (!src)
478		return;
479
480	dst = pScreen->GetScreenPixmap(pScreen);
481
482	gc = GetScratchGC(pScrn->depth, pScreen);
483	ValidateGC(&dst->drawable, gc);
484
485	force = info->accel_state->force;
486	info->accel_state->force = TRUE;
487	(*gc->ops->CopyArea)(&src->drawable, &dst->drawable, gc, 0, 0,
488			     pScrn->virtualX, pScrn->virtualY, 0, 0);
489	info->accel_state->force = force;
490
491	FreeScratchGC(gc);
492
493	pScreen->canDoBGNoneRoot = TRUE;
494	destroy_pixmap_for_fbcon(pScrn);
495	return;
496}
497
498static void
499drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
500			     struct drmmode_scanout *scanout)
501{
502	if (scanout->pixmap) {
503		drmmode_destroy_bo_pixmap(scanout->pixmap);
504		scanout->pixmap = NULL;
505	}
506
507	if (scanout->bo) {
508		drmModeRmFB(drmmode->fd, scanout->fb_id);
509		scanout->fb_id = 0;
510		radeon_bo_unmap(scanout->bo);
511		radeon_bo_unref(scanout->bo);
512		scanout->bo = NULL;
513	}
514}
515
516static void
517drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc)
518{
519	if (drmmode_crtc->flip_pending) {
520		drmmode_crtc->scanout_destroy[0] = drmmode_crtc->scanout[0];
521		drmmode_crtc->scanout[0].pixmap = NULL;
522		drmmode_crtc->scanout[0].bo = NULL;
523		drmmode_crtc->scanout_destroy[1] = drmmode_crtc->scanout[1];
524		drmmode_crtc->scanout[1].pixmap = NULL;
525		drmmode_crtc->scanout[1].bo = NULL;
526	} else {
527		drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
528					     &drmmode_crtc->scanout[0]);
529		drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
530					     &drmmode_crtc->scanout[1]);
531	}
532
533	if (drmmode_crtc->scanout_damage) {
534		DamageDestroy(drmmode_crtc->scanout_damage);
535		drmmode_crtc->scanout_damage = NULL;
536		RegionUninit(&drmmode_crtc->scanout_last_region);
537	}
538}
539
540void
541drmmode_scanout_free(ScrnInfoPtr scrn)
542{
543	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
544	int c;
545
546	for (c = 0; c < xf86_config->num_crtc; c++)
547		drmmode_crtc_scanout_free(xf86_config->crtc[c]->driver_private);
548}
549
550static PixmapPtr
551drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout,
552			    int width, int height)
553{
554	ScrnInfoPtr pScrn = crtc->scrn;
555	RADEONInfoPtr info = RADEONPTR(pScrn);
556	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
557	drmmode_ptr drmmode = drmmode_crtc->drmmode;
558	struct radeon_surface surface;
559	uint32_t tiling = RADEON_CREATE_PIXMAP_TILING_MACRO;
560	int pitch;
561
562	if (scanout->pixmap) {
563		if (scanout->width == width && scanout->height == height)
564			return scanout->pixmap;
565
566		drmmode_crtc_scanout_destroy(drmmode, scanout);
567	}
568
569	if (info->ChipFamily >= CHIP_FAMILY_R600)
570		tiling |= RADEON_CREATE_PIXMAP_TILING_MICRO;
571	scanout->bo = radeon_alloc_pixmap_bo(pScrn, width, height, pScrn->depth,
572					     tiling, pScrn->bitsPerPixel,
573					     &pitch, &surface, &tiling);
574	if (scanout->bo == NULL)
575		goto error;
576
577	if (drmModeAddFB(drmmode->fd, width, height, pScrn->depth,
578			   pScrn->bitsPerPixel, pitch,
579			   scanout->bo->handle,
580			   &scanout->fb_id) != 0) {
581		ErrorF("failed to add scanout fb\n");
582		goto error;
583	}
584
585	scanout->pixmap = drmmode_create_bo_pixmap(pScrn,
586						 width, height,
587						 pScrn->depth,
588						 pScrn->bitsPerPixel,
589						 pitch, scanout->bo, NULL);
590	if (scanout->pixmap) {
591		scanout->width = width;
592		scanout->height = height;
593	} else {
594		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
595			   "Couldn't allocate scanout pixmap for CRTC\n");
596error:
597		drmmode_crtc_scanout_destroy(drmmode, scanout);
598	}
599
600	return scanout->pixmap;
601}
602
603static void
604radeon_screen_damage_report(DamagePtr damage, RegionPtr region, void *closure)
605{
606	/* Only keep track of the extents */
607	RegionUninit(&damage->damage);
608	damage->damage.data = NULL;
609}
610
611static Bool
612drmmode_can_use_hw_cursor(xf86CrtcPtr crtc)
613{
614	RADEONInfoPtr info = RADEONPTR(crtc->scrn);
615
616	/* Check for Option "SWcursor" */
617	if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE))
618		return FALSE;
619
620	/* Fall back to SW cursor if the CRTC is transformed */
621	if (crtc->transformPresent)
622		return FALSE;
623
624#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7
625	/* Xorg doesn't correctly handle cursor position transform in the
626	 * rotation case
627	 */
628	if (crtc->driverIsPerformingTransform &&
629	    (crtc->rotation & 0xf) != RR_Rotate_0)
630		return FALSE;
631#endif
632
633#if defined(RADEON_PIXMAP_SHARING)
634	/* HW cursor not supported with RandR 1.4 multihead up to 1.18.99.901 */
635	if (xorgGetVersion() <= XORG_VERSION_NUMERIC(1,18,99,901,0) &&
636	    !xorg_list_is_empty(&crtc->scrn->pScreen->pixmap_dirty_list))
637		return FALSE;
638#endif
639
640	return TRUE;
641}
642
643static void
644drmmode_crtc_update_tear_free(xf86CrtcPtr crtc)
645{
646	RADEONInfoPtr info = RADEONPTR(crtc->scrn);
647	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
648	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
649	int i;
650
651	drmmode_crtc->tear_free = FALSE;
652
653	for (i = 0; i < xf86_config->num_output; i++) {
654		xf86OutputPtr output = xf86_config->output[i];
655		drmmode_output_private_ptr drmmode_output = output->driver_private;
656
657		if (output->crtc != crtc)
658			continue;
659
660		if (drmmode_output->tear_free == 1 ||
661		    (drmmode_output->tear_free == 2 &&
662		     (radeon_is_gpu_screen(crtc->scrn->pScreen) ||
663		      info->shadow_primary ||
664		      crtc->transformPresent || crtc->rotation != RR_Rotate_0))) {
665			drmmode_crtc->tear_free = TRUE;
666			return;
667		}
668	}
669}
670
671#if XF86_CRTC_VERSION >= 4
672
673#if XF86_CRTC_VERSION < 7
674#define XF86DriverTransformOutput TRUE
675#define XF86DriverTransformNone FALSE
676#endif
677
678static Bool
679drmmode_handle_transform(xf86CrtcPtr crtc)
680{
681	Bool ret;
682
683	if (crtc->transformPresent || crtc->rotation != RR_Rotate_0)
684	    crtc->driverIsPerformingTransform = XF86DriverTransformOutput;
685	else
686	    crtc->driverIsPerformingTransform = XF86DriverTransformNone;
687
688	ret = xf86CrtcRotate(crtc);
689
690	crtc->driverIsPerformingTransform &= ret && crtc->transform_in_use;
691
692	return ret;
693}
694
695#else
696
697static Bool
698drmmode_handle_transform(xf86CrtcPtr crtc)
699{
700	return xf86CrtcRotate(crtc);
701}
702
703#endif
704
705#ifdef RADEON_PIXMAP_SHARING
706
707static void
708drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
709				  unsigned scanout_id, int *fb_id, int *x,
710				  int *y)
711{
712	ScrnInfoPtr scrn = crtc->scrn;
713	ScreenPtr screen = scrn->pScreen;
714	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
715
716	if (drmmode_crtc->tear_free &&
717	    !drmmode_crtc->scanout[1].pixmap) {
718		RegionPtr region;
719		BoxPtr box;
720
721		drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
722					    mode->HDisplay,
723					    mode->VDisplay);
724		region = &drmmode_crtc->scanout_last_region;
725		RegionUninit(region);
726		region->data = NULL;
727		box = RegionExtents(region);
728		box->x1 = crtc->x;
729		box->y1 = crtc->y;
730		box->x2 = crtc->x + mode->HDisplay;
731		box->y2 = crtc->y + mode->VDisplay;
732	}
733
734	if (scanout_id != drmmode_crtc->scanout_id) {
735		PixmapDirtyUpdatePtr dirty = NULL;
736
737		xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list,
738					 ent) {
739			if (dirty->src == crtc->randr_crtc->scanout_pixmap &&
740			    dirty->slave_dst ==
741			    drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap) {
742				dirty->slave_dst =
743					drmmode_crtc->scanout[scanout_id].pixmap;
744				break;
745			}
746		}
747
748		if (!drmmode_crtc->tear_free) {
749			GCPtr gc = GetScratchGC(scrn->depth, screen);
750
751			ValidateGC(&drmmode_crtc->scanout[0].pixmap->drawable, gc);
752			gc->ops->CopyArea(&drmmode_crtc->scanout[1].pixmap->drawable,
753					  &drmmode_crtc->scanout[0].pixmap->drawable,
754					  gc, 0, 0, mode->HDisplay, mode->VDisplay,
755					  0, 0);
756			FreeScratchGC(gc);
757			radeon_cs_flush_indirect(scrn);
758			radeon_bo_wait(drmmode_crtc->scanout[0].bo);
759		}
760	}
761
762	*fb_id = drmmode_crtc->scanout[scanout_id].fb_id;
763	*x = *y = 0;
764	drmmode_crtc->scanout_id = scanout_id;
765}
766
767#endif /* RADEON_PIXMAP_SHARING */
768
769static void
770drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
771			    unsigned scanout_id, int *fb_id, int *x, int *y)
772{
773	ScrnInfoPtr scrn = crtc->scrn;
774	ScreenPtr screen = scrn->pScreen;
775	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
776
777	drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0],
778				    mode->HDisplay, mode->VDisplay);
779	if (drmmode_crtc->tear_free) {
780		drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
781					    mode->HDisplay, mode->VDisplay);
782	}
783
784	if (drmmode_crtc->scanout[0].pixmap &&
785	    (!drmmode_crtc->tear_free || drmmode_crtc->scanout[1].pixmap)) {
786		RegionPtr region;
787		BoxPtr box;
788
789		if (!drmmode_crtc->scanout_damage) {
790			drmmode_crtc->scanout_damage =
791				DamageCreate(radeon_screen_damage_report,
792					     NULL, DamageReportRawRegion,
793					     TRUE, screen, NULL);
794			DamageRegister(&screen->GetScreenPixmap(screen)->drawable,
795				       drmmode_crtc->scanout_damage);
796		}
797
798		region = DamageRegion(drmmode_crtc->scanout_damage);
799		RegionUninit(region);
800		region->data = NULL;
801		box = RegionExtents(region);
802		box->x1 = 0;
803		box->y1 = 0;
804		box->x2 = max(box->x2, scrn->virtualX);
805		box->y2 = max(box->y2, scrn->virtualY);
806
807		*fb_id = drmmode_crtc->scanout[scanout_id].fb_id;
808		*x = *y = 0;
809
810		radeon_scanout_do_update(crtc, scanout_id);
811		radeon_bo_wait(drmmode_crtc->scanout[scanout_id].bo);
812	}
813}
814
815static Bool
816drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
817		     Rotation rotation, int x, int y)
818{
819	ScrnInfoPtr pScrn = crtc->scrn;
820	ScreenPtr pScreen = pScrn->pScreen;
821	RADEONInfoPtr info = RADEONPTR(pScrn);
822	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
823	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
824	unsigned scanout_id = 0;
825	drmmode_ptr drmmode = drmmode_crtc->drmmode;
826	int saved_x, saved_y;
827	Rotation saved_rotation;
828	DisplayModeRec saved_mode;
829	uint32_t *output_ids = NULL;
830	int output_count = 0;
831	Bool ret = FALSE;
832	int i;
833	int fb_id;
834	drmModeModeInfo kmode;
835
836	saved_mode = crtc->mode;
837	saved_x = crtc->x;
838	saved_y = crtc->y;
839	saved_rotation = crtc->rotation;
840
841	if (mode) {
842		crtc->mode = *mode;
843		crtc->x = x;
844		crtc->y = y;
845		crtc->rotation = rotation;
846
847		output_ids = calloc(sizeof(uint32_t), xf86_config->num_output);
848		if (!output_ids)
849			goto done;
850
851		for (i = 0; i < xf86_config->num_output; i++) {
852			xf86OutputPtr output = xf86_config->output[i];
853			drmmode_output_private_ptr drmmode_output;
854
855			if (output->crtc != crtc)
856				continue;
857
858			drmmode_output = output->driver_private;
859			output_ids[output_count] = drmmode_output->mode_output->connector_id;
860			output_count++;
861		}
862
863		if (!drmmode_handle_transform(crtc))
864			goto done;
865
866		drmmode_crtc_update_tear_free(crtc);
867		if (drmmode_crtc->tear_free)
868			scanout_id = drmmode_crtc->scanout_id;
869
870		crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
871				       crtc->gamma_blue, crtc->gamma_size);
872
873		drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
874
875		fb_id = drmmode->fb_id;
876#ifdef RADEON_PIXMAP_SHARING
877		if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) {
878			drmmode_crtc_prime_scanout_update(crtc, mode, scanout_id,
879							  &fb_id, &x, &y);
880		} else
881#endif
882		if (drmmode_crtc->rotate.fb_id) {
883			fb_id = drmmode_crtc->rotate.fb_id;
884			x = y = 0;
885
886		} else if (!radeon_is_gpu_screen(pScreen) &&
887			   (drmmode_crtc->tear_free ||
888#if XF86_CRTC_VERSION >= 4
889			    crtc->driverIsPerformingTransform ||
890#endif
891			    info->shadow_primary)) {
892			drmmode_crtc_scanout_update(crtc, mode, scanout_id,
893						    &fb_id, &x, &y);
894		}
895
896		if (fb_id == 0) {
897			if (drmModeAddFB(drmmode->fd,
898					 pScrn->virtualX,
899					 pScrn->virtualY,
900					 pScrn->depth, pScrn->bitsPerPixel,
901					 pScrn->displayWidth * info->pixel_bytes,
902					 info->front_bo->handle,
903					 &drmmode->fb_id) < 0) {
904				ErrorF("failed to add fb\n");
905				goto done;
906			}
907
908			fb_id = drmmode->fb_id;
909		}
910
911		/* Wait for any pending flip to finish */
912		do {} while (drmmode_crtc->flip_pending &&
913			     drmHandleEvent(drmmode->fd,
914					    &drmmode->event_context) > 0);
915
916		if (drmModeSetCrtc(drmmode->fd,
917				   drmmode_crtc->mode_crtc->crtc_id,
918				   fb_id, x, y, output_ids,
919				   output_count, &kmode) != 0) {
920			xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
921				   "failed to set mode: %s\n", strerror(errno));
922			goto done;
923		} else
924			ret = TRUE;
925
926		if (pScreen)
927			xf86CrtcSetScreenSubpixelOrder(pScreen);
928
929		drmmode_crtc->need_modeset = FALSE;
930
931		/* go through all the outputs and force DPMS them back on? */
932		for (i = 0; i < xf86_config->num_output; i++) {
933			xf86OutputPtr output = xf86_config->output[i];
934
935			if (output->crtc != crtc)
936				continue;
937
938			output->funcs->dpms(output, DPMSModeOn);
939		}
940	}
941
942	/* Compute index of this CRTC into xf86_config->crtc */
943	for (i = 0; i < xf86_config->num_crtc; i++) {
944		if (xf86_config->crtc[i] != crtc)
945			continue;
946
947		if (!crtc->enabled || drmmode_can_use_hw_cursor(crtc))
948			info->hwcursor_disabled &= ~(1 << i);
949		else
950			info->hwcursor_disabled |= 1 << i;
951
952		break;
953	}
954
955#ifndef HAVE_XF86_CURSOR_RESET_CURSOR
956	if (!info->hwcursor_disabled)
957		xf86_reload_cursors(pScreen);
958#endif
959
960done:
961	if (!ret) {
962		crtc->x = saved_x;
963		crtc->y = saved_y;
964		crtc->rotation = saved_rotation;
965		crtc->mode = saved_mode;
966	} else {
967		crtc->active = TRUE;
968
969		if (fb_id != drmmode_crtc->scanout[scanout_id].fb_id)
970			drmmode_crtc_scanout_free(drmmode_crtc);
971		else if (!drmmode_crtc->tear_free) {
972			drmmode_crtc_scanout_destroy(drmmode,
973						     &drmmode_crtc->scanout[1]);
974		}
975	}
976
977	free(output_ids);
978
979	return ret;
980}
981
982static void
983drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
984{
985
986}
987
988static void
989drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
990{
991	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
992	drmmode_ptr drmmode = drmmode_crtc->drmmode;
993
994#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7
995	if (crtc->driverIsPerformingTransform) {
996		x += crtc->x;
997		y += crtc->y;
998		xf86CrtcTransformCursorPos(crtc, &x, &y);
999	}
1000#endif
1001
1002	drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
1003}
1004
1005#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7
1006
1007static int
1008drmmode_cursor_src_offset(Rotation rotation, int width, int height,
1009			  int x_dst, int y_dst)
1010{
1011	int t;
1012
1013	switch (rotation & 0xf) {
1014	case RR_Rotate_90:
1015		t = x_dst;
1016		x_dst = height - y_dst - 1;
1017		y_dst = t;
1018		break;
1019	case RR_Rotate_180:
1020		x_dst = width - x_dst - 1;
1021		y_dst = height - y_dst - 1;
1022		break;
1023	case RR_Rotate_270:
1024		t = x_dst;
1025		x_dst = y_dst;
1026		y_dst = width - t - 1;
1027		break;
1028	}
1029
1030	if (rotation & RR_Reflect_X)
1031		x_dst = width - x_dst - 1;
1032	if (rotation & RR_Reflect_Y)
1033		y_dst = height - y_dst - 1;
1034
1035	return y_dst * height + x_dst;
1036}
1037
1038#endif
1039
1040static void
1041drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
1042{
1043	ScrnInfoPtr pScrn = crtc->scrn;
1044	RADEONInfoPtr info = RADEONPTR(pScrn);
1045	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1046	uint32_t *ptr;
1047
1048	/* cursor should be mapped already */
1049	ptr = (uint32_t *)(drmmode_crtc->cursor_bo->ptr);
1050
1051#if XF86_CRTC_VERSION >= 4 && XF86_CRTC_VERSION < 7
1052	if (crtc->driverIsPerformingTransform) {
1053		uint32_t cursor_w = info->cursor_w, cursor_h = info->cursor_h;
1054		int dstx, dsty;
1055		int srcoffset;
1056
1057		for (dsty = 0; dsty < cursor_h; dsty++) {
1058			for (dstx = 0; dstx < cursor_w; dstx++) {
1059				srcoffset = drmmode_cursor_src_offset(crtc->rotation,
1060								      cursor_w,
1061								      cursor_h,
1062								      dstx, dsty);
1063
1064				ptr[dsty * info->cursor_w + dstx] =
1065					cpu_to_le32(image[srcoffset]);
1066			}
1067		}
1068	} else
1069#endif
1070	{
1071		uint32_t cursor_size = info->cursor_w * info->cursor_h;
1072		int i;
1073
1074		for (i = 0; i < cursor_size; i++)
1075			ptr[i] = cpu_to_le32(image[i]);
1076	}
1077}
1078
1079#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,903,0)
1080
1081static Bool drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 * image)
1082{
1083	if (!drmmode_can_use_hw_cursor(crtc))
1084		return FALSE;
1085
1086	drmmode_load_cursor_argb(crtc, image);
1087	return TRUE;
1088}
1089
1090#endif
1091
1092static void
1093drmmode_hide_cursor (xf86CrtcPtr crtc)
1094{
1095	ScrnInfoPtr pScrn = crtc->scrn;
1096	RADEONInfoPtr info = RADEONPTR(pScrn);
1097	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1098	drmmode_ptr drmmode = drmmode_crtc->drmmode;
1099
1100	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0,
1101			 info->cursor_w, info->cursor_h);
1102
1103}
1104
1105static void
1106drmmode_show_cursor (xf86CrtcPtr crtc)
1107{
1108	ScrnInfoPtr pScrn = crtc->scrn;
1109	RADEONInfoPtr info = RADEONPTR(pScrn);
1110	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1111	drmmode_ptr drmmode = drmmode_crtc->drmmode;
1112	uint32_t handle = drmmode_crtc->cursor_bo->handle;
1113	static Bool use_set_cursor2 = TRUE;
1114
1115	if (use_set_cursor2) {
1116	    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
1117	    CursorPtr cursor = xf86_config->cursor;
1118	    int xhot = cursor->bits->xhot;
1119	    int yhot = cursor->bits->yhot;
1120	    int ret;
1121
1122	    if (crtc->rotation != RR_Rotate_0 &&
1123		crtc->rotation != (RR_Rotate_180 | RR_Reflect_X |
1124				   RR_Reflect_Y)) {
1125		int t;
1126
1127		/* Reflect & rotate hotspot position */
1128		if (crtc->rotation & RR_Reflect_X)
1129		    xhot = info->cursor_w - xhot - 1;
1130		if (crtc->rotation & RR_Reflect_Y)
1131		    yhot = info->cursor_h - yhot - 1;
1132
1133		switch (crtc->rotation & 0xf) {
1134		case RR_Rotate_90:
1135		    t = xhot;
1136		    xhot = yhot;
1137		    yhot = info->cursor_w - t - 1;
1138		    break;
1139		case RR_Rotate_180:
1140		    xhot = info->cursor_w - xhot - 1;
1141		    yhot = info->cursor_h - yhot - 1;
1142		    break;
1143		case RR_Rotate_270:
1144		    t = xhot;
1145		    xhot = info->cursor_h - yhot - 1;
1146		    yhot = t;
1147		}
1148	    }
1149
1150	    ret =
1151		drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
1152				  handle, info->cursor_w, info->cursor_h,
1153				  xhot, yhot);
1154	    if (ret == -EINVAL)
1155		use_set_cursor2 = FALSE;
1156	    else
1157		return;
1158	}
1159
1160	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle,
1161			 info->cursor_w, info->cursor_h);
1162}
1163
1164/* Xorg expects a non-NULL return value from drmmode_crtc_shadow_allocate, and
1165 * passes that back to drmmode_crtc_scanout_create; it doesn't use it for
1166 * anything else.
1167 */
1168static void *
1169drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
1170{
1171	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1172
1173	if (!drmmode_crtc_scanout_create(crtc, &drmmode_crtc->rotate, width,
1174					 height))
1175		return NULL;
1176
1177	return (void*)~0UL;
1178}
1179
1180static PixmapPtr
1181drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
1182{
1183	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1184
1185	if (!data) {
1186		drmmode_crtc_scanout_create(crtc, &drmmode_crtc->rotate, width,
1187					    height);
1188	}
1189
1190	return drmmode_crtc->rotate.pixmap;
1191}
1192
1193static void
1194drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
1195{
1196	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1197	drmmode_ptr drmmode = drmmode_crtc->drmmode;
1198
1199	drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->rotate);
1200}
1201
1202static void
1203drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green,
1204                      uint16_t *blue, int size)
1205{
1206	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1207	drmmode_ptr drmmode = drmmode_crtc->drmmode;
1208
1209	drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
1210			    size, red, green, blue);
1211}
1212
1213#ifdef RADEON_PIXMAP_SHARING
1214static Bool
1215drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
1216{
1217	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1218	unsigned scanout_id = drmmode_crtc->scanout_id;
1219	ScreenPtr screen = crtc->scrn->pScreen;
1220	PixmapDirtyUpdatePtr dirty;
1221
1222	xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
1223		if (dirty->slave_dst != drmmode_crtc->scanout[scanout_id].pixmap)
1224			continue;
1225
1226		PixmapStopDirtyTracking(dirty->src, dirty->slave_dst);
1227		drmmode_crtc_scanout_free(drmmode_crtc);
1228		break;
1229	}
1230
1231	if (!ppix)
1232		return TRUE;
1233
1234	if (!drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0],
1235					 ppix->drawable.width,
1236					 ppix->drawable.height))
1237		return FALSE;
1238
1239	if (drmmode_crtc->tear_free &&
1240	    !drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
1241					 ppix->drawable.width,
1242					 ppix->drawable.height)) {
1243		drmmode_crtc_scanout_free(drmmode_crtc);
1244		return FALSE;
1245	}
1246
1247#ifdef HAS_DIRTYTRACKING_ROTATION
1248	PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[scanout_id].pixmap,
1249				 0, 0, 0, 0, RR_Rotate_0);
1250#elif defined(HAS_DIRTYTRACKING2)
1251	PixmapStartDirtyTracking2(ppix, drmmode_crtc->scanout[scanout_id].pixmap,
1252				  0, 0, 0, 0);
1253#else
1254	PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[scanout_id].pixmap, 0, 0);
1255#endif
1256	return TRUE;
1257}
1258#endif
1259
1260static xf86CrtcFuncsRec drmmode_crtc_funcs = {
1261    .dpms = drmmode_crtc_dpms,
1262    .set_mode_major = drmmode_set_mode_major,
1263    .set_cursor_colors = drmmode_set_cursor_colors,
1264    .set_cursor_position = drmmode_set_cursor_position,
1265    .show_cursor = drmmode_show_cursor,
1266    .hide_cursor = drmmode_hide_cursor,
1267    .load_cursor_argb = drmmode_load_cursor_argb,
1268#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,903,0)
1269    .load_cursor_argb_check = drmmode_load_cursor_argb_check,
1270#endif
1271
1272    .gamma_set = drmmode_crtc_gamma_set,
1273    .shadow_create = drmmode_crtc_shadow_create,
1274    .shadow_allocate = drmmode_crtc_shadow_allocate,
1275    .shadow_destroy = drmmode_crtc_shadow_destroy,
1276    .destroy = NULL, /* XXX */
1277#ifdef RADEON_PIXMAP_SHARING
1278    .set_scanout_pixmap = drmmode_set_scanout_pixmap,
1279#endif
1280};
1281
1282int drmmode_get_crtc_id(xf86CrtcPtr crtc)
1283{
1284	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1285	return drmmode_crtc->hw_id;
1286}
1287
1288void drmmode_crtc_hw_id(xf86CrtcPtr crtc)
1289{
1290	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1291	ScrnInfoPtr pScrn = crtc->scrn;
1292	RADEONInfoPtr info = RADEONPTR(pScrn);
1293	struct drm_radeon_info ginfo;
1294	int r;
1295	uint32_t tmp;
1296
1297	memset(&ginfo, 0, sizeof(ginfo));
1298	ginfo.request = 0x4;
1299	tmp = drmmode_crtc->mode_crtc->crtc_id;
1300	ginfo.value = (uintptr_t)&tmp;
1301	r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
1302	if (r) {
1303		drmmode_crtc->hw_id = -1;
1304		return;
1305	}
1306	drmmode_crtc->hw_id = tmp;
1307}
1308
1309static unsigned int
1310drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num)
1311{
1312	xf86CrtcPtr crtc;
1313	drmmode_crtc_private_ptr drmmode_crtc;
1314	RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
1315
1316	crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
1317	if (crtc == NULL)
1318		return 0;
1319
1320	drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
1321	drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]);
1322	drmmode_crtc->drmmode = drmmode;
1323	drmmode_crtc->dpms_mode = DPMSModeOff;
1324	drmmode_crtc->pending_dpms_mode = DPMSModeOff;
1325	crtc->driver_private = drmmode_crtc;
1326	drmmode_crtc_hw_id(crtc);
1327
1328	/* Mark num'th crtc as in use on this device. */
1329	pRADEONEnt->assigned_crtcs |= (1 << num);
1330	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1331		       "Allocated crtc nr. %d to this screen.\n", num);
1332
1333	return 1;
1334}
1335
1336static xf86OutputStatus
1337drmmode_output_detect(xf86OutputPtr output)
1338{
1339	/* go to the hw and retrieve a new output struct */
1340	drmmode_output_private_ptr drmmode_output = output->driver_private;
1341	drmmode_ptr drmmode = drmmode_output->drmmode;
1342	xf86OutputStatus status;
1343	drmModeFreeConnector(drmmode_output->mode_output);
1344
1345	drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
1346	if (!drmmode_output->mode_output)
1347		return XF86OutputStatusDisconnected;
1348
1349	switch (drmmode_output->mode_output->connection) {
1350	case DRM_MODE_CONNECTED:
1351		status = XF86OutputStatusConnected;
1352		break;
1353	case DRM_MODE_DISCONNECTED:
1354		status = XF86OutputStatusDisconnected;
1355		break;
1356	default:
1357	case DRM_MODE_UNKNOWNCONNECTION:
1358		status = XF86OutputStatusUnknown;
1359		break;
1360	}
1361	return status;
1362}
1363
1364static Bool
1365drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
1366{
1367	return MODE_OK;
1368}
1369
1370static DisplayModePtr
1371drmmode_output_get_modes(xf86OutputPtr output)
1372{
1373	drmmode_output_private_ptr drmmode_output = output->driver_private;
1374	drmModeConnectorPtr koutput = drmmode_output->mode_output;
1375	drmmode_ptr drmmode = drmmode_output->drmmode;
1376	int i;
1377	DisplayModePtr Modes = NULL, Mode;
1378	drmModePropertyPtr props;
1379	xf86MonPtr mon = NULL;
1380
1381	if (!koutput)
1382		return NULL;
1383
1384	/* look for an EDID property */
1385	for (i = 0; i < koutput->count_props; i++) {
1386		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
1387		if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
1388			if (!strcmp(props->name, "EDID")) {
1389				if (drmmode_output->edid_blob)
1390					drmModeFreePropertyBlob(drmmode_output->edid_blob);
1391				drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
1392			}
1393		}
1394		if (props)
1395			drmModeFreeProperty(props);
1396	}
1397
1398	if (drmmode_output->edid_blob) {
1399		mon = xf86InterpretEDID(output->scrn->scrnIndex,
1400					drmmode_output->edid_blob->data);
1401		if (mon && drmmode_output->edid_blob->length > 128)
1402			mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
1403	}
1404	xf86OutputSetEDID(output, mon);
1405
1406	/* modes should already be available */
1407	for (i = 0; i < koutput->count_modes; i++) {
1408		Mode = xnfalloc(sizeof(DisplayModeRec));
1409
1410		drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode);
1411		Modes = xf86ModesAdd(Modes, Mode);
1412
1413	}
1414	return Modes;
1415}
1416
1417static void
1418drmmode_output_destroy(xf86OutputPtr output)
1419{
1420	drmmode_output_private_ptr drmmode_output = output->driver_private;
1421	int i;
1422
1423	if (drmmode_output->edid_blob)
1424		drmModeFreePropertyBlob(drmmode_output->edid_blob);
1425	for (i = 0; i < drmmode_output->num_props; i++) {
1426		drmModeFreeProperty(drmmode_output->props[i].mode_prop);
1427		free(drmmode_output->props[i].atoms);
1428	}
1429	for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) {
1430		drmModeFreeEncoder(drmmode_output->mode_encoders[i]);
1431	}
1432	free(drmmode_output->mode_encoders);
1433	free(drmmode_output->props);
1434	drmModeFreeConnector(drmmode_output->mode_output);
1435	free(drmmode_output);
1436	output->driver_private = NULL;
1437}
1438
1439static void
1440drmmode_output_dpms(xf86OutputPtr output, int mode)
1441{
1442	drmmode_output_private_ptr drmmode_output = output->driver_private;
1443	xf86CrtcPtr crtc = output->crtc;
1444	drmModeConnectorPtr koutput = drmmode_output->mode_output;
1445	drmmode_ptr drmmode = drmmode_output->drmmode;
1446
1447	if (!koutput)
1448		return;
1449
1450	if (mode != DPMSModeOn && crtc) {
1451		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1452
1453		drmmode_do_crtc_dpms(crtc, mode);
1454
1455		/* Wait for any pending flip to finish */
1456		if (drmmode_crtc->flip_pending)
1457			return;
1458	}
1459
1460	drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id,
1461				    drmmode_output->dpms_enum_id, mode);
1462
1463	if (mode == DPMSModeOn && crtc) {
1464	    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1465
1466	    if (drmmode_crtc->need_modeset)
1467		drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x,
1468				       crtc->y);
1469	    else
1470		drmmode_do_crtc_dpms(crtc, mode);
1471	}
1472}
1473
1474
1475static Bool
1476drmmode_property_ignore(drmModePropertyPtr prop)
1477{
1478    if (!prop)
1479	return TRUE;
1480    /* ignore blob prop */
1481    if (prop->flags & DRM_MODE_PROP_BLOB)
1482	return TRUE;
1483    /* ignore standard property */
1484    if (!strcmp(prop->name, "EDID") ||
1485	    !strcmp(prop->name, "DPMS"))
1486	return TRUE;
1487
1488    return FALSE;
1489}
1490
1491static void
1492drmmode_output_create_resources(xf86OutputPtr output)
1493{
1494    RADEONInfoPtr info = RADEONPTR(output->scrn);
1495    drmmode_output_private_ptr drmmode_output = output->driver_private;
1496    drmModeConnectorPtr mode_output = drmmode_output->mode_output;
1497    drmmode_ptr drmmode = drmmode_output->drmmode;
1498    drmModePropertyPtr drmmode_prop, tearfree_prop;
1499    int i, j, err;
1500
1501    drmmode_output->props = calloc(mode_output->count_props + 1, sizeof(drmmode_prop_rec));
1502    if (!drmmode_output->props)
1503	return;
1504
1505    drmmode_output->num_props = 0;
1506    for (i = 0, j = 0; i < mode_output->count_props; i++) {
1507	drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]);
1508	if (drmmode_property_ignore(drmmode_prop)) {
1509	    drmModeFreeProperty(drmmode_prop);
1510	    continue;
1511	}
1512	drmmode_output->props[j].mode_prop = drmmode_prop;
1513	drmmode_output->props[j].value = mode_output->prop_values[i];
1514	drmmode_output->num_props++;
1515	j++;
1516    }
1517
1518    /* Userspace-only property for TearFree */
1519    tearfree_prop = calloc(1, sizeof(*tearfree_prop));
1520    tearfree_prop->flags = DRM_MODE_PROP_ENUM;
1521    strncpy(tearfree_prop->name, "TearFree", 8);
1522    tearfree_prop->count_enums = 3;
1523    tearfree_prop->enums = calloc(tearfree_prop->count_enums,
1524				  sizeof(*tearfree_prop->enums));
1525    strncpy(tearfree_prop->enums[0].name, "off", 3);
1526    strncpy(tearfree_prop->enums[1].name, "on", 2);
1527    tearfree_prop->enums[1].value = 1;
1528    strncpy(tearfree_prop->enums[2].name, "auto", 4);
1529    tearfree_prop->enums[2].value = 2;
1530    drmmode_output->props[j].mode_prop = tearfree_prop;
1531    drmmode_output->props[j].value = info->tear_free;
1532    drmmode_output->tear_free = info->tear_free;
1533    drmmode_output->num_props++;
1534
1535    for (i = 0; i < drmmode_output->num_props; i++) {
1536	drmmode_prop_ptr p = &drmmode_output->props[i];
1537	drmmode_prop = p->mode_prop;
1538
1539	if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) {
1540	    INT32 range[2];
1541	    INT32 value = p->value;
1542
1543	    p->num_atoms = 1;
1544	    p->atoms = calloc(p->num_atoms, sizeof(Atom));
1545	    if (!p->atoms)
1546		continue;
1547	    p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
1548	    range[0] = drmmode_prop->values[0];
1549	    range[1] = drmmode_prop->values[1];
1550	    err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
1551		    FALSE, TRUE,
1552		    drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
1553		    2, range);
1554	    if (err != 0) {
1555		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
1556			"RRConfigureOutputProperty error, %d\n", err);
1557	    }
1558	    err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
1559		    XA_INTEGER, 32, PropModeReplace, 1, &value, FALSE, TRUE);
1560	    if (err != 0) {
1561		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
1562			"RRChangeOutputProperty error, %d\n", err);
1563	    }
1564	} else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) {
1565	    p->num_atoms = drmmode_prop->count_enums + 1;
1566	    p->atoms = calloc(p->num_atoms, sizeof(Atom));
1567	    if (!p->atoms)
1568		continue;
1569	    p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
1570	    for (j = 1; j <= drmmode_prop->count_enums; j++) {
1571		struct drm_mode_property_enum *e = &drmmode_prop->enums[j-1];
1572		p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE);
1573	    }
1574	    err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
1575		    FALSE, FALSE,
1576		    drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
1577		    p->num_atoms - 1, (INT32 *)&p->atoms[1]);
1578	    if (err != 0) {
1579		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
1580			"RRConfigureOutputProperty error, %d\n", err);
1581	    }
1582	    for (j = 0; j < drmmode_prop->count_enums; j++)
1583		if (drmmode_prop->enums[j].value == p->value)
1584		    break;
1585	    /* there's always a matching value */
1586	    err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
1587		    XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, TRUE);
1588	    if (err != 0) {
1589		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
1590			"RRChangeOutputProperty error, %d\n", err);
1591	    }
1592	}
1593    }
1594}
1595
1596static Bool
1597drmmode_output_set_property(xf86OutputPtr output, Atom property,
1598		RRPropertyValuePtr value)
1599{
1600    drmmode_output_private_ptr drmmode_output = output->driver_private;
1601    drmmode_ptr drmmode = drmmode_output->drmmode;
1602    int i;
1603
1604    for (i = 0; i < drmmode_output->num_props; i++) {
1605	drmmode_prop_ptr p = &drmmode_output->props[i];
1606
1607	if (p->atoms[0] != property)
1608	    continue;
1609
1610	if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) {
1611	    uint32_t val;
1612
1613	    if (value->type != XA_INTEGER || value->format != 32 ||
1614		    value->size != 1)
1615		return FALSE;
1616	    val = *(uint32_t *)value->data;
1617
1618	    drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id,
1619		    p->mode_prop->prop_id, (uint64_t)val);
1620	    return TRUE;
1621	} else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) {
1622	    Atom	atom;
1623	    const char	*name;
1624	    int		j;
1625
1626	    if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
1627		return FALSE;
1628	    memcpy(&atom, value->data, 4);
1629	    name = NameForAtom(atom);
1630
1631	    /* search for matching name string, then set its value down */
1632	    for (j = 0; j < p->mode_prop->count_enums; j++) {
1633		if (!strcmp(p->mode_prop->enums[j].name, name)) {
1634		    if (i == (drmmode_output->num_props - 1)) {
1635			if (drmmode_output->tear_free != j) {
1636			    xf86CrtcPtr crtc = output->crtc;
1637
1638			    drmmode_output->tear_free = j;
1639			    if (crtc) {
1640				drmmode_set_mode_major(crtc, &crtc->mode,
1641						       crtc->rotation,
1642						       crtc->x, crtc->y);
1643			    }
1644			}
1645		    } else {
1646			drmModeConnectorSetProperty(drmmode->fd,
1647						    drmmode_output->output_id,
1648						    p->mode_prop->prop_id,
1649						    p->mode_prop->enums[j].value);
1650		    }
1651
1652		    return TRUE;
1653		}
1654	    }
1655	}
1656    }
1657
1658    return TRUE;
1659}
1660
1661static Bool
1662drmmode_output_get_property(xf86OutputPtr output, Atom property)
1663{
1664    return TRUE;
1665}
1666
1667static const xf86OutputFuncsRec drmmode_output_funcs = {
1668    .dpms = drmmode_output_dpms,
1669    .create_resources = drmmode_output_create_resources,
1670    .set_property = drmmode_output_set_property,
1671    .get_property = drmmode_output_get_property,
1672#if 0
1673
1674    .save = drmmode_crt_save,
1675    .restore = drmmode_crt_restore,
1676    .mode_fixup = drmmode_crt_mode_fixup,
1677    .prepare = drmmode_output_prepare,
1678    .mode_set = drmmode_crt_mode_set,
1679    .commit = drmmode_output_commit,
1680#endif
1681    .detect = drmmode_output_detect,
1682    .mode_valid = drmmode_output_mode_valid,
1683
1684    .get_modes = drmmode_output_get_modes,
1685    .destroy = drmmode_output_destroy
1686};
1687
1688static int subpixel_conv_table[7] = { 0, SubPixelUnknown,
1689				      SubPixelHorizontalRGB,
1690				      SubPixelHorizontalBGR,
1691				      SubPixelVerticalRGB,
1692				      SubPixelVerticalBGR,
1693				      SubPixelNone };
1694
1695const char *output_names[] = { "None",
1696			       "VGA",
1697			       "DVI",
1698			       "DVI",
1699			       "DVI",
1700			       "Composite",
1701			       "S-video",
1702			       "LVDS",
1703			       "CTV",
1704			       "DIN",
1705			       "DisplayPort",
1706			       "HDMI",
1707			       "HDMI",
1708			       "TV",
1709			       "eDP"
1710};
1711
1712#define NUM_OUTPUT_NAMES (sizeof(output_names) / sizeof(output_names[0]))
1713
1714static xf86OutputPtr find_output(ScrnInfoPtr pScrn, int id)
1715{
1716	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1717	int i;
1718	for (i = 0; i < xf86_config->num_output; i++) {
1719		xf86OutputPtr output = xf86_config->output[i];
1720		drmmode_output_private_ptr drmmode_output;
1721
1722		drmmode_output = output->driver_private;
1723		if (drmmode_output->output_id == id)
1724			return output;
1725	}
1726	return NULL;
1727}
1728
1729static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id, char **path)
1730{
1731	char *conn;
1732	char conn_id[5];
1733	int id, len;
1734	char *blob_data;
1735
1736	if (!path_blob)
1737		return -1;
1738
1739	blob_data = path_blob->data;
1740	/* we only handle MST paths for now */
1741	if (strncmp(blob_data, "mst:", 4))
1742		return -1;
1743
1744	conn = strchr(blob_data + 4, '-');
1745	if (!conn)
1746		return -1;
1747	len = conn - (blob_data + 4);
1748	if (len + 1 > 5)
1749		return -1;
1750	memcpy(conn_id, blob_data + 4, len);
1751	conn_id[len] = '\0';
1752	id = strtoul(conn_id, NULL, 10);
1753
1754	*conn_base_id = id;
1755
1756	*path = conn + 1;
1757	return 0;
1758}
1759
1760static void
1761drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name,
1762		    drmModePropertyBlobPtr path_blob, int *num_dvi, int *num_hdmi)
1763{
1764	xf86OutputPtr output;
1765	int conn_id;
1766	char *extra_path;
1767
1768	output = NULL;
1769	if (parse_path_blob(path_blob, &conn_id, &extra_path) == 0)
1770		output = find_output(pScrn, conn_id);
1771	if (output) {
1772		snprintf(name, 32, "%s-%s", output->name, extra_path);
1773	} else {
1774		if (koutput->connector_type >= NUM_OUTPUT_NAMES)
1775			snprintf(name, 32, "Unknown%d-%d", koutput->connector_type,
1776				 koutput->connector_type_id - 1);
1777#ifdef RADEON_PIXMAP_SHARING
1778		else if (pScrn->is_gpu)
1779			snprintf(name, 32, "%s-%d-%d",
1780				 output_names[koutput->connector_type], pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1,
1781				 koutput->connector_type_id - 1);
1782#endif
1783		else {
1784			/* need to do smart conversion here for compat with non-kms ATI driver */
1785			if (koutput->connector_type_id == 1) {
1786				switch(koutput->connector_type) {
1787				case DRM_MODE_CONNECTOR_DVII:
1788				case DRM_MODE_CONNECTOR_DVID:
1789				case DRM_MODE_CONNECTOR_DVIA:
1790					snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], *num_dvi);
1791					(*num_dvi)++;
1792					break;
1793				case DRM_MODE_CONNECTOR_HDMIA:
1794				case DRM_MODE_CONNECTOR_HDMIB:
1795					snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], *num_hdmi);
1796					(*num_hdmi)++;
1797					break;
1798				case DRM_MODE_CONNECTOR_VGA:
1799				case DRM_MODE_CONNECTOR_DisplayPort:
1800					snprintf(name, 32, "%s-%d", output_names[koutput->connector_type],
1801						 koutput->connector_type_id - 1);
1802					break;
1803				default:
1804					snprintf(name, 32, "%s", output_names[koutput->connector_type]);
1805					break;
1806				}
1807			} else {
1808				snprintf(name, 32, "%s-%d", output_names[koutput->connector_type],
1809					 koutput->connector_type_id - 1);
1810			}
1811		}
1812	}
1813}
1814
1815static unsigned int
1816drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, int *num_dvi, int *num_hdmi, int dynamic)
1817{
1818	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1819	RADEONInfoPtr info = RADEONPTR(pScrn);
1820	xf86OutputPtr output;
1821	drmModeConnectorPtr koutput;
1822	drmModeEncoderPtr *kencoders = NULL;
1823	drmmode_output_private_ptr drmmode_output;
1824	drmModePropertyPtr props;
1825	drmModePropertyBlobPtr path_blob = NULL;
1826	char name[32];
1827	int i;
1828	const char *s;
1829
1830	koutput = drmModeGetConnector(drmmode->fd, mode_res->connectors[num]);
1831	if (!koutput)
1832		return 0;
1833
1834	for (i = 0; i < koutput->count_props; i++) {
1835		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
1836		if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
1837			if (!strcmp(props->name, "PATH")) {
1838				path_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
1839				drmModeFreeProperty(props);
1840				break;
1841			}
1842			drmModeFreeProperty(props);
1843		}
1844	}
1845
1846	kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders);
1847	if (!kencoders) {
1848		goto out_free_encoders;
1849	}
1850
1851	for (i = 0; i < koutput->count_encoders; i++) {
1852		kencoders[i] = drmModeGetEncoder(drmmode->fd, koutput->encoders[i]);
1853		if (!kencoders[i]) {
1854			goto out_free_encoders;
1855		}
1856	}
1857
1858	drmmode_create_name(pScrn, koutput, name, path_blob, num_dvi, num_hdmi);
1859	if (path_blob)
1860		drmModeFreePropertyBlob(path_blob);
1861
1862	if (path_blob && dynamic) {
1863		/* See if we have an output with this name already
1864		 * and hook stuff up.
1865		 */
1866		for (i = 0; i < xf86_config->num_output; i++) {
1867			output = xf86_config->output[i];
1868
1869			if (strncmp(output->name, name, 32))
1870				continue;
1871
1872			drmmode_output = output->driver_private;
1873			drmmode_output->output_id = mode_res->connectors[num];
1874			drmmode_output->mode_output = koutput;
1875			for (i = 0; i < koutput->count_encoders; i++)
1876				drmModeFreeEncoder(kencoders[i]);
1877			free(kencoders);
1878			return 0;
1879		}
1880	}
1881
1882	if (xf86IsEntityShared(pScrn->entityList[0])) {
1883		if ((s = xf86GetOptValString(info->Options, OPTION_ZAPHOD_HEADS))) {
1884			if (!RADEONZaphodStringMatches(pScrn, s, name))
1885				goto out_free_encoders;
1886		} else {
1887			if (!info->IsSecondary && (num != 0))
1888				goto out_free_encoders;
1889			else if (info->IsSecondary && (num != 1))
1890				goto out_free_encoders;
1891		}
1892	}
1893
1894	output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name);
1895	if (!output) {
1896		goto out_free_encoders;
1897	}
1898
1899	drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1);
1900	if (!drmmode_output) {
1901		xf86OutputDestroy(output);
1902		goto out_free_encoders;
1903	}
1904
1905	drmmode_output->output_id = mode_res->connectors[num];
1906	drmmode_output->mode_output = koutput;
1907	drmmode_output->mode_encoders = kencoders;
1908	drmmode_output->drmmode = drmmode;
1909	output->mm_width = koutput->mmWidth;
1910	output->mm_height = koutput->mmHeight;
1911
1912	output->subpixel_order = subpixel_conv_table[koutput->subpixel];
1913	output->interlaceAllowed = TRUE;
1914	output->doubleScanAllowed = TRUE;
1915	output->driver_private = drmmode_output;
1916
1917	output->possible_crtcs = 0xffffffff;
1918	for (i = 0; i < koutput->count_encoders; i++) {
1919		output->possible_crtcs &= kencoders[i]->possible_crtcs;
1920	}
1921	/* work out the possible clones later */
1922	output->possible_clones = 0;
1923
1924	for (i = 0; i < koutput->count_props; i++) {
1925		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
1926		if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
1927			if (!strcmp(props->name, "DPMS")) {
1928				drmmode_output->dpms_enum_id = koutput->props[i];
1929				drmModeFreeProperty(props);
1930				break;
1931			}
1932			drmModeFreeProperty(props);
1933		}
1934	}
1935
1936	if (dynamic) {
1937		output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output);
1938		drmmode_output_create_resources(output);
1939	}
1940
1941	return 1;
1942out_free_encoders:
1943	if (kencoders){
1944		for (i = 0; i < koutput->count_encoders; i++)
1945			drmModeFreeEncoder(kencoders[i]);
1946		free(kencoders);
1947	}
1948	drmModeFreeConnector(koutput);
1949	return 0;
1950}
1951
1952uint32_t find_clones(ScrnInfoPtr scrn, xf86OutputPtr output)
1953{
1954	drmmode_output_private_ptr drmmode_output = output->driver_private, clone_drmout;
1955	int i;
1956	xf86OutputPtr clone_output;
1957	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
1958	int index_mask = 0;
1959
1960	if (drmmode_output->enc_clone_mask == 0)
1961		return index_mask;
1962
1963	for (i = 0; i < xf86_config->num_output; i++) {
1964		clone_output = xf86_config->output[i];
1965		clone_drmout = clone_output->driver_private;
1966		if (output == clone_output)
1967			continue;
1968
1969		if (clone_drmout->enc_mask == 0)
1970			continue;
1971		if (drmmode_output->enc_clone_mask == clone_drmout->enc_mask)
1972			index_mask |= (1 << i);
1973	}
1974	return index_mask;
1975}
1976
1977
1978static void
1979drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, drmModeResPtr mode_res)
1980{
1981	int i, j;
1982	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
1983
1984	for (i = 0; i < xf86_config->num_output; i++) {
1985		xf86OutputPtr output = xf86_config->output[i];
1986		drmmode_output_private_ptr drmmode_output;
1987
1988		drmmode_output = output->driver_private;
1989		drmmode_output->enc_clone_mask = 0xff;
1990		/* and all the possible encoder clones for this output together */
1991		for (j = 0; j < drmmode_output->mode_output->count_encoders; j++)
1992		{
1993			int k;
1994			for (k = 0; k < mode_res->count_encoders; k++) {
1995				if (mode_res->encoders[k] == drmmode_output->mode_encoders[j]->encoder_id)
1996					drmmode_output->enc_mask |= (1 << k);
1997			}
1998
1999			drmmode_output->enc_clone_mask &= drmmode_output->mode_encoders[j]->possible_clones;
2000		}
2001	}
2002
2003	for (i = 0; i < xf86_config->num_output; i++) {
2004		xf86OutputPtr output = xf86_config->output[i];
2005		output->possible_clones = find_clones(scrn, output);
2006	}
2007}
2008
2009/* returns height alignment in pixels */
2010int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling)
2011{
2012	RADEONInfoPtr info = RADEONPTR(scrn);
2013	int height_align = 1;
2014
2015	if (info->ChipFamily >= CHIP_FAMILY_R600) {
2016		if (tiling & RADEON_TILING_MACRO)
2017			height_align =  info->num_channels * 8;
2018		else if (tiling & RADEON_TILING_MICRO)
2019			height_align = 8;
2020		else
2021			height_align = 8;
2022	} else {
2023		if (tiling & RADEON_TILING_MICRO_SQUARE)
2024			height_align =  32;
2025		else if (tiling)
2026			height_align = 16;
2027		else
2028			height_align = 1;
2029	}
2030	return height_align;
2031}
2032
2033/* returns pitch alignment in pixels */
2034int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling)
2035{
2036	RADEONInfoPtr info = RADEONPTR(scrn);
2037	int pitch_align = 1;
2038
2039	if (info->ChipFamily >= CHIP_FAMILY_R600) {
2040		if (tiling & RADEON_TILING_MACRO) {
2041			/* general surface requirements */
2042			pitch_align = MAX(info->num_banks,
2043					  (((info->group_bytes / 8) / bpe) * info->num_banks)) * 8;
2044			/* further restrictions for scanout */
2045			pitch_align = MAX(info->num_banks * 8, pitch_align);
2046		} else if (tiling & RADEON_TILING_MICRO) {
2047			/* general surface requirements */
2048			pitch_align = MAX(8, (info->group_bytes / (8 * bpe)));
2049			/* further restrictions for scanout */
2050			pitch_align = MAX(info->group_bytes / bpe, pitch_align);
2051		} else {
2052			if (info->have_tiling_info)
2053				/* linear aligned requirements */
2054				pitch_align = MAX(64, info->group_bytes / bpe);
2055			else
2056				/* default to 512 elements if we don't know the real
2057				 * group size otherwise the kernel may reject the CS
2058				 * if the group sizes don't match as the pitch won't
2059				 * be aligned properly.
2060				 */
2061				pitch_align = 512;
2062		}
2063	} else {
2064		/* general surface requirements */
2065		if (tiling)
2066			pitch_align = 256 / bpe;
2067		else
2068			pitch_align = 64;
2069	}
2070	return pitch_align;
2071}
2072
2073/* returns base alignment in bytes */
2074int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling)
2075{
2076	RADEONInfoPtr info = RADEONPTR(scrn);
2077	int pixel_align = drmmode_get_pitch_align(scrn, bpe, tiling);
2078	int height_align = drmmode_get_height_align(scrn, tiling);
2079	int base_align = RADEON_GPU_PAGE_SIZE;
2080
2081	if (info->ChipFamily >= CHIP_FAMILY_R600) {
2082		if (tiling & RADEON_TILING_MACRO)
2083			base_align = MAX(info->num_banks * info->num_channels * 8 * 8 * bpe,
2084					 pixel_align * bpe * height_align);
2085		else {
2086			if (info->have_tiling_info)
2087				base_align = info->group_bytes;
2088			else
2089				/* default to 512 if we don't know the real
2090				 * group size otherwise the kernel may reject the CS
2091				 * if the group sizes don't match as the base won't
2092				 * be aligned properly.
2093				 */
2094				base_align = 512;
2095		}
2096	}
2097	return base_align;
2098}
2099
2100static Bool
2101drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
2102{
2103	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
2104	drmmode_crtc_private_ptr
2105		    drmmode_crtc = xf86_config->crtc[0]->driver_private;
2106	drmmode_ptr drmmode = drmmode_crtc->drmmode;
2107	RADEONInfoPtr info = RADEONPTR(scrn);
2108	struct radeon_bo *old_front = NULL;
2109	ScreenPtr   screen = xf86ScrnToScreen(scrn);
2110	uint32_t    old_fb_id;
2111	int	    i, pitch, old_width, old_height, old_pitch;
2112	int aligned_height;
2113	uint32_t screen_size;
2114	int cpp = info->pixel_bytes;
2115	struct radeon_bo *front_bo;
2116	struct radeon_surface surface;
2117	struct radeon_surface *psurface;
2118	uint32_t tiling_flags = 0, base_align;
2119	PixmapPtr ppix = screen->GetScreenPixmap(screen);
2120	void *fb_shadow;
2121	xRectangle rect;
2122	Bool force;
2123	GCPtr gc;
2124
2125	if (scrn->virtualX == width && scrn->virtualY == height)
2126		return TRUE;
2127
2128	front_bo = info->front_bo;
2129	radeon_cs_flush_indirect(scrn);
2130
2131	if (front_bo)
2132		radeon_bo_wait(front_bo);
2133
2134	if (info->allowColorTiling && !info->shadow_primary) {
2135		if (info->ChipFamily >= CHIP_FAMILY_R600) {
2136			if (info->allowColorTiling2D) {
2137				tiling_flags |= RADEON_TILING_MACRO;
2138			} else {
2139				tiling_flags |= RADEON_TILING_MICRO;
2140			}
2141		} else
2142			tiling_flags |= RADEON_TILING_MACRO;
2143	}
2144
2145	pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(scrn, cpp, tiling_flags)) * cpp;
2146	aligned_height = RADEON_ALIGN(height, drmmode_get_height_align(scrn, tiling_flags));
2147	screen_size = RADEON_ALIGN(pitch * aligned_height, RADEON_GPU_PAGE_SIZE);
2148	base_align = 4096;
2149	if (info->ChipFamily >= CHIP_FAMILY_R600) {
2150		memset(&surface, 0, sizeof(struct radeon_surface));
2151		surface.npix_x = width;
2152		surface.npix_y = height;
2153		surface.npix_z = 1;
2154		surface.blk_w = 1;
2155		surface.blk_h = 1;
2156		surface.blk_d = 1;
2157		surface.array_size = 1;
2158		surface.last_level = 0;
2159		surface.bpe = cpp;
2160		surface.nsamples = 1;
2161		surface.flags = RADEON_SURF_SCANOUT;
2162		/* we are requiring a recent enough libdrm version */
2163		surface.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
2164		surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
2165		surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
2166		if (tiling_flags & RADEON_TILING_MICRO) {
2167			surface.flags = RADEON_SURF_CLR(surface.flags, MODE);
2168			surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2169		}
2170		if (tiling_flags & RADEON_TILING_MACRO) {
2171			surface.flags = RADEON_SURF_CLR(surface.flags, MODE);
2172			surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
2173		}
2174		if (radeon_surface_best(info->surf_man, &surface)) {
2175			return FALSE;
2176		}
2177		if (radeon_surface_init(info->surf_man, &surface)) {
2178			return FALSE;
2179		}
2180		screen_size = surface.bo_size;
2181		base_align = surface.bo_alignment;
2182		pitch = surface.level[0].pitch_bytes;
2183		tiling_flags = 0;
2184		switch (surface.level[0].mode) {
2185		case RADEON_SURF_MODE_2D:
2186			tiling_flags |= RADEON_TILING_MACRO;
2187			tiling_flags |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT;
2188			tiling_flags |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT;
2189			tiling_flags |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
2190			if (surface.tile_split)
2191				tiling_flags |= eg_tile_split(surface.tile_split)
2192						<< RADEON_TILING_EG_TILE_SPLIT_SHIFT;
2193			break;
2194		case RADEON_SURF_MODE_1D:
2195			tiling_flags |= RADEON_TILING_MICRO;
2196			break;
2197		default:
2198			break;
2199		}
2200		info->front_surface = surface;
2201	}
2202
2203	xf86DrvMsg(scrn->scrnIndex, X_INFO,
2204		   "Allocate new frame buffer %dx%d stride %d\n",
2205		   width, height, pitch / cpp);
2206
2207	old_width = scrn->virtualX;
2208	old_height = scrn->virtualY;
2209	old_pitch = scrn->displayWidth;
2210	old_fb_id = drmmode->fb_id;
2211	drmmode->fb_id = 0;
2212	old_front = info->front_bo;
2213
2214	scrn->virtualX = width;
2215	scrn->virtualY = height;
2216	scrn->displayWidth = pitch / cpp;
2217
2218	info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size, base_align,
2219					info->shadow_primary ?
2220					RADEON_GEM_DOMAIN_GTT :
2221					RADEON_GEM_DOMAIN_VRAM,
2222					tiling_flags ? RADEON_GEM_NO_CPU_ACCESS : 0);
2223	if (!info->front_bo)
2224		goto fail;
2225
2226#if X_BYTE_ORDER == X_BIG_ENDIAN
2227	switch (cpp) {
2228	case 4:
2229	    tiling_flags |= RADEON_TILING_SWAP_32BIT;
2230	    break;
2231	case 2:
2232	    tiling_flags |= RADEON_TILING_SWAP_16BIT;
2233	    break;
2234	}
2235	if (info->ChipFamily < CHIP_FAMILY_R600 &&
2236	    info->r600_shadow_fb && tiling_flags)
2237	    tiling_flags |= RADEON_TILING_SURFACE;
2238#endif
2239	if (tiling_flags)
2240	    radeon_bo_set_tiling(info->front_bo, tiling_flags, pitch);
2241
2242	if (!info->r600_shadow_fb) {
2243		psurface = radeon_get_pixmap_surface(ppix);
2244		*psurface = info->front_surface;
2245		screen->ModifyPixmapHeader(ppix,
2246					   width, height, -1, -1, pitch, NULL);
2247	} else {
2248		if (radeon_bo_map(info->front_bo, 1))
2249			goto fail;
2250		fb_shadow = calloc(1, screen_size);
2251		if (fb_shadow == NULL)
2252			goto fail;
2253		free(info->fb_shadow);
2254		info->fb_shadow = fb_shadow;
2255		screen->ModifyPixmapHeader(ppix,
2256					   width, height, -1, -1, pitch,
2257					   info->fb_shadow);
2258	}
2259
2260	if (info->use_glamor)
2261		radeon_glamor_create_screen_resources(scrn->pScreen);
2262
2263	if (!info->r600_shadow_fb) {
2264		if (!radeon_set_pixmap_bo(ppix, info->front_bo))
2265			goto fail;
2266	}
2267
2268	/* Clear new buffer */
2269	gc = GetScratchGC(ppix->drawable.depth, scrn->pScreen);
2270	force = info->accel_state->force;
2271	info->accel_state->force = TRUE;
2272	ValidateGC(&ppix->drawable, gc);
2273	rect.x = 0;
2274	rect.y = 0;
2275	rect.width = width;
2276	rect.height = height;
2277	(*gc->ops->PolyFillRect)(&ppix->drawable, gc, 1, &rect);
2278	FreeScratchGC(gc);
2279	info->accel_state->force = force;
2280	radeon_cs_flush_indirect(scrn);
2281	radeon_bo_wait(info->front_bo);
2282
2283	for (i = 0; i < xf86_config->num_crtc; i++) {
2284		xf86CrtcPtr crtc = xf86_config->crtc[i];
2285
2286		if (!crtc->enabled)
2287			continue;
2288
2289		drmmode_set_mode_major(crtc, &crtc->mode,
2290				       crtc->rotation, crtc->x, crtc->y);
2291	}
2292
2293	if (old_fb_id)
2294		drmModeRmFB(drmmode->fd, old_fb_id);
2295	if (old_front)
2296		radeon_bo_unref(old_front);
2297
2298	radeon_kms_update_vram_limit(scrn, screen_size);
2299	return TRUE;
2300
2301 fail:
2302	if (info->front_bo)
2303		radeon_bo_unref(info->front_bo);
2304	info->front_bo = old_front;
2305	scrn->virtualX = old_width;
2306	scrn->virtualY = old_height;
2307	scrn->displayWidth = old_pitch;
2308	drmmode->fb_id = old_fb_id;
2309
2310	return FALSE;
2311}
2312
2313static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
2314	drmmode_xf86crtc_resize
2315};
2316
2317void
2318drmmode_clear_pending_flip(xf86CrtcPtr crtc)
2319{
2320	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
2321
2322	drmmode_crtc->flip_pending = FALSE;
2323
2324	if (!crtc->enabled ||
2325	    (drmmode_crtc->pending_dpms_mode != DPMSModeOn &&
2326	     drmmode_crtc->dpms_mode != drmmode_crtc->pending_dpms_mode)) {
2327		xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
2328		int o;
2329
2330		for (o = 0; o < xf86_config->num_output; o++) {
2331			xf86OutputPtr output = xf86_config->output[o];
2332
2333			if (output->crtc != crtc)
2334				continue;
2335
2336			drmmode_output_dpms(output, drmmode_crtc->pending_dpms_mode);
2337		}
2338
2339		drmmode_crtc_dpms(crtc, drmmode_crtc->pending_dpms_mode);
2340	}
2341
2342	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
2343				     &drmmode_crtc->scanout_destroy[0]);
2344	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
2345				     &drmmode_crtc->scanout_destroy[1]);
2346}
2347
2348static void
2349drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data)
2350{
2351	drmmode_flipdata_ptr flipdata = event_data;
2352
2353	if (--flipdata->flip_count == 0) {
2354		if (!flipdata->fe_crtc)
2355			flipdata->fe_crtc = crtc;
2356		flipdata->abort(flipdata->fe_crtc, flipdata->event_data);
2357		free(flipdata);
2358	}
2359
2360	drmmode_clear_pending_flip(crtc);
2361}
2362
2363static void
2364drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data)
2365{
2366	RADEONInfoPtr info = RADEONPTR(crtc->scrn);
2367	drmmode_flipdata_ptr flipdata = event_data;
2368
2369	/* Is this the event whose info shall be delivered to higher level? */
2370	if (crtc == flipdata->fe_crtc) {
2371		/* Yes: Cache msc, ust for later delivery. */
2372		flipdata->fe_frame = frame;
2373		flipdata->fe_usec = usec;
2374	}
2375
2376	if (--flipdata->flip_count == 0) {
2377		/* Deliver MSC & UST from reference/current CRTC to flip event
2378		 * handler
2379		 */
2380		if (flipdata->fe_crtc)
2381			flipdata->handler(flipdata->fe_crtc, flipdata->fe_frame,
2382					  flipdata->fe_usec, flipdata->event_data);
2383		else
2384			flipdata->handler(crtc, frame, usec, flipdata->event_data);
2385
2386		/* Release framebuffer */
2387		drmModeRmFB(info->drmmode.fd, flipdata->old_fb_id);
2388
2389		free(flipdata);
2390	}
2391
2392	drmmode_clear_pending_flip(crtc);
2393}
2394
2395
2396#if HAVE_NOTIFY_FD
2397static void
2398drm_notify_fd(int fd, int ready, void *data)
2399#else
2400static void
2401drm_wakeup_handler(pointer data, int err, pointer p)
2402#endif
2403{
2404	drmmode_ptr drmmode = data;
2405#if !HAVE_NOTIFY_FD
2406	fd_set *read_mask = p;
2407
2408	if (err >= 0 && FD_ISSET(drmmode->fd, read_mask))
2409#endif
2410	{
2411		drmHandleEvent(drmmode->fd, &drmmode->event_context);
2412	}
2413}
2414
2415static Bool drmmode_probe_page_flip_target(drmmode_ptr drmmode)
2416{
2417#ifdef DRM_CAP_PAGE_FLIP_TARGET
2418	uint64_t cap_value;
2419
2420	return drmGetCap(drmmode->fd, DRM_CAP_PAGE_FLIP_TARGET,
2421			 &cap_value) == 0 && cap_value != 0;
2422#else
2423	return FALSE;
2424#endif
2425}
2426
2427static int
2428drmmode_page_flip(drmmode_crtc_private_ptr drmmode_crtc, int fb_id,
2429		  uint32_t flags, uintptr_t drm_queue_seq)
2430{
2431	drmmode_ptr drmmode = drmmode_crtc->drmmode;
2432
2433	flags |= DRM_MODE_PAGE_FLIP_EVENT;
2434	return drmModePageFlip(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
2435			       fb_id, flags, (void*)drm_queue_seq);
2436}
2437
2438int
2439drmmode_page_flip_target_absolute(RADEONEntPtr pRADEONEnt,
2440				  drmmode_crtc_private_ptr drmmode_crtc,
2441				  int fb_id, uint32_t flags,
2442				  uintptr_t drm_queue_seq, uint32_t target_msc)
2443{
2444#ifdef DRM_MODE_PAGE_FLIP_TARGET
2445	if (pRADEONEnt->has_page_flip_target) {
2446		drmmode_ptr drmmode = drmmode_crtc->drmmode;
2447
2448		flags |= DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE;
2449		return drmModePageFlipTarget(drmmode->fd,
2450					     drmmode_crtc->mode_crtc->crtc_id,
2451					     fb_id, flags, (void*)drm_queue_seq,
2452					     target_msc);
2453	}
2454#endif
2455
2456	return drmmode_page_flip(drmmode_crtc, fb_id, flags, drm_queue_seq);
2457}
2458
2459int
2460drmmode_page_flip_target_relative(RADEONEntPtr pRADEONEnt,
2461				  drmmode_crtc_private_ptr drmmode_crtc,
2462				  int fb_id, uint32_t flags,
2463				  uintptr_t drm_queue_seq, uint32_t target_msc)
2464{
2465#ifdef DRM_MODE_PAGE_FLIP_TARGET
2466	if (pRADEONEnt->has_page_flip_target) {
2467		drmmode_ptr drmmode = drmmode_crtc->drmmode;
2468
2469		flags |= DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_PAGE_FLIP_TARGET_RELATIVE;
2470		return drmModePageFlipTarget(drmmode->fd,
2471					     drmmode_crtc->mode_crtc->crtc_id,
2472					     fb_id, flags, (void*)drm_queue_seq,
2473					     target_msc);
2474	}
2475#endif
2476
2477	return drmmode_page_flip(drmmode_crtc, fb_id, flags, drm_queue_seq);
2478}
2479
2480Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
2481{
2482	RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
2483	RADEONInfoPtr info = RADEONPTR(pScrn);
2484	int i, num_dvi = 0, num_hdmi = 0;
2485	drmModeResPtr mode_res;
2486	unsigned int crtcs_needed = 0;
2487#ifdef RADEON_PIXMAP_SHARING
2488	char *bus_id_string, *provider_name;
2489#endif
2490
2491	xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
2492
2493	drmmode->scrn = pScrn;
2494	drmmode->cpp = cpp;
2495	mode_res = drmModeGetResources(drmmode->fd);
2496	if (!mode_res)
2497		return FALSE;
2498
2499	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
2500		       "Initializing outputs ...\n");
2501	for (i = 0; i < mode_res->count_connectors; i++)
2502		crtcs_needed += drmmode_output_init(pScrn, drmmode, mode_res,
2503						    i, &num_dvi, &num_hdmi, 0);
2504	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
2505		       "%d crtcs needed for screen.\n", crtcs_needed);
2506
2507	if (info->r600_shadow_fb) {
2508		/* Rotation requires hardware acceleration */
2509		drmmode_crtc_funcs.shadow_allocate = NULL;
2510		drmmode_crtc_funcs.shadow_create = NULL;
2511		drmmode_crtc_funcs.shadow_destroy = NULL;
2512	}
2513
2514	drmmode->count_crtcs = mode_res->count_crtcs;
2515	xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width, mode_res->max_height);
2516
2517	for (i = 0; i < mode_res->count_crtcs; i++)
2518		if (!xf86IsEntityShared(pScrn->entityList[0]) ||
2519		    (crtcs_needed && !(pRADEONEnt->assigned_crtcs & (1 << i))))
2520			crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, i);
2521
2522	/* All ZaphodHeads outputs provided with matching crtcs? */
2523	if (xf86IsEntityShared(pScrn->entityList[0]) && (crtcs_needed > 0))
2524		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2525			   "%d ZaphodHeads crtcs unavailable. Some outputs will stay off.\n",
2526			   crtcs_needed);
2527
2528	/* workout clones */
2529	drmmode_clones_init(pScrn, drmmode, mode_res);
2530
2531#ifdef RADEON_PIXMAP_SHARING
2532	bus_id_string = DRICreatePCIBusID(info->PciInfo);
2533	XNFasprintf(&provider_name, "%s @ %s", pScrn->chipset, bus_id_string);
2534	free(bus_id_string);
2535	xf86ProviderSetup(pScrn, NULL, provider_name);
2536	free(provider_name);
2537#endif
2538
2539	xf86InitialConfiguration(pScrn, TRUE);
2540
2541	drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION;
2542	drmmode->event_context.vblank_handler = radeon_drm_queue_handler;
2543	drmmode->event_context.page_flip_handler = radeon_drm_queue_handler;
2544
2545	pRADEONEnt->has_page_flip_target = drmmode_probe_page_flip_target(drmmode);
2546
2547	drmModeFreeResources(mode_res);
2548	return TRUE;
2549}
2550
2551void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
2552{
2553	RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
2554	RADEONInfoPtr info = RADEONPTR(pScrn);
2555
2556	if (info->dri2.pKernelDRMVersion->version_minor < 4)
2557		return;
2558
2559	info->drmmode_inited = TRUE;
2560	if (pRADEONEnt->fd_wakeup_registered != serverGeneration) {
2561#if HAVE_NOTIFY_FD
2562		SetNotifyFd(drmmode->fd, drm_notify_fd, X_NOTIFY_READ, drmmode);
2563#else
2564		AddGeneralSocket(drmmode->fd);
2565		RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
2566				drm_wakeup_handler, drmmode);
2567#endif
2568		pRADEONEnt->fd_wakeup_registered = serverGeneration;
2569		pRADEONEnt->fd_wakeup_ref = 1;
2570	} else
2571		pRADEONEnt->fd_wakeup_ref++;
2572}
2573
2574void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
2575{
2576	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
2577	RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
2578	RADEONInfoPtr info = RADEONPTR(pScrn);
2579	int c;
2580
2581	if (info->dri2.pKernelDRMVersion->version_minor < 4 || !info->drmmode_inited)
2582		return;
2583
2584	if (pRADEONEnt->fd_wakeup_registered == serverGeneration &&
2585	    !--pRADEONEnt->fd_wakeup_ref) {
2586#if HAVE_NOTIFY_FD
2587		RemoveNotifyFd(drmmode->fd);
2588#else
2589		RemoveGeneralSocket(drmmode->fd);
2590		RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
2591				drm_wakeup_handler, drmmode);
2592#endif
2593	}
2594
2595	for (c = 0; c < config->num_crtc; c++)
2596		drmmode_crtc_scanout_free(config->crtc[c]->driver_private);
2597}
2598
2599
2600Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr)
2601{
2602	drmmode->bufmgr = bufmgr;
2603	return TRUE;
2604}
2605
2606
2607
2608void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo)
2609{
2610	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
2611	xf86CrtcPtr crtc = xf86_config->crtc[id];
2612	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
2613
2614	drmmode_crtc->cursor_bo = bo;
2615}
2616
2617void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y)
2618{
2619	xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
2620	xf86OutputPtr  output = config->output[config->compat_output];
2621	xf86CrtcPtr	crtc = output->crtc;
2622
2623	if (crtc && crtc->enabled) {
2624		drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
2625				       x, y);
2626	}
2627}
2628
2629Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
2630			       Bool set_hw)
2631{
2632	xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
2633	int c;
2634
2635	for (c = 0; c < config->num_crtc; c++) {
2636		xf86CrtcPtr	crtc = config->crtc[c];
2637		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
2638		xf86OutputPtr	output = NULL;
2639		int		o;
2640
2641		/* Skip disabled CRTCs */
2642		if (!crtc->enabled) {
2643			if (set_hw) {
2644				drmmode_do_crtc_dpms(crtc, DPMSModeOff);
2645				drmModeSetCrtc(drmmode->fd,
2646					       drmmode_crtc->mode_crtc->crtc_id,
2647					       0, 0, 0, NULL, 0, NULL);
2648			}
2649			continue;
2650		}
2651
2652		if (config->output[config->compat_output]->crtc == crtc)
2653			output = config->output[config->compat_output];
2654		else
2655		{
2656			for (o = 0; o < config->num_output; o++)
2657				if (config->output[o]->crtc == crtc)
2658				{
2659					output = config->output[o];
2660					break;
2661				}
2662		}
2663		/* paranoia */
2664		if (!output)
2665			continue;
2666
2667		/* Mark that we'll need to re-set the mode for sure */
2668		memset(&crtc->mode, 0, sizeof(crtc->mode));
2669		if (!crtc->desiredMode.CrtcHDisplay)
2670		{
2671			DisplayModePtr  mode = xf86OutputFindClosestMode (output, pScrn->currentMode);
2672
2673			if (!mode)
2674				return FALSE;
2675			crtc->desiredMode = *mode;
2676			crtc->desiredRotation = RR_Rotate_0;
2677			crtc->desiredX = 0;
2678			crtc->desiredY = 0;
2679		}
2680
2681		if (set_hw) {
2682			if (!crtc->funcs->set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation,
2683							 crtc->desiredX, crtc->desiredY))
2684				return FALSE;
2685		} else {
2686			crtc->mode = crtc->desiredMode;
2687			crtc->rotation = crtc->desiredRotation;
2688			crtc->x = crtc->desiredX;
2689			crtc->y = crtc->desiredY;
2690			if (!drmmode_handle_transform(crtc))
2691				return FALSE;
2692		}
2693	}
2694	return TRUE;
2695}
2696
2697Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
2698{
2699    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2700
2701    if (xf86_config->num_crtc) {
2702	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
2703		       "Initializing kms color map\n");
2704	if (!miCreateDefColormap(pScreen))
2705	    return FALSE;
2706	/* all radeons support 10 bit CLUTs */
2707	if (!xf86HandleColormaps(pScreen, 256, 10,
2708				 NULL, NULL,
2709				 CMAP_PALETTED_TRUECOLOR
2710#if 0 /* This option messes up text mode! (eich@suse.de) */
2711				 | CMAP_LOAD_EVEN_IF_OFFSCREEN
2712#endif
2713				 | CMAP_RELOAD_ON_MODE_SWITCH))
2714	    return FALSE;
2715    }
2716    return TRUE;
2717}
2718
2719static Bool
2720drmmode_find_output(ScrnInfoPtr scrn, int output_id, int *num_dvi,
2721		    int *num_hdmi)
2722{
2723	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
2724	int i;
2725
2726	for (i = 0; i < config->num_output; i++) {
2727		xf86OutputPtr output = config->output[i];
2728		drmmode_output_private_ptr drmmode_output = output->driver_private;
2729
2730		if (drmmode_output->output_id == output_id) {
2731			switch(drmmode_output->mode_output->connector_type) {
2732			case DRM_MODE_CONNECTOR_DVII:
2733			case DRM_MODE_CONNECTOR_DVID:
2734			case DRM_MODE_CONNECTOR_DVIA:
2735				(*num_dvi)++;
2736				break;
2737			case DRM_MODE_CONNECTOR_HDMIA:
2738			case DRM_MODE_CONNECTOR_HDMIB:
2739				(*num_hdmi)++;
2740				break;
2741			}
2742
2743			return TRUE;
2744		}
2745	}
2746
2747	return FALSE;
2748}
2749
2750void
2751radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode)
2752{
2753	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
2754	RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
2755	drmModeResPtr mode_res;
2756	int i, j;
2757	Bool found;
2758	Bool changed = FALSE;
2759	int num_dvi = 0, num_hdmi = 0;
2760
2761	mode_res = drmModeGetResources(drmmode->fd);
2762	if (!mode_res)
2763		goto out;
2764
2765restart_destroy:
2766	for (i = 0; i < config->num_output; i++) {
2767		xf86OutputPtr output = config->output[i];
2768		drmmode_output_private_ptr drmmode_output = output->driver_private;
2769		found = FALSE;
2770		for (j = 0; j < mode_res->count_connectors; j++) {
2771			if (mode_res->connectors[j] == drmmode_output->output_id) {
2772				found = TRUE;
2773				break;
2774			}
2775		}
2776		if (found)
2777			continue;
2778
2779		drmModeFreeConnector(drmmode_output->mode_output);
2780		drmmode_output->mode_output = NULL;
2781		drmmode_output->output_id = -1;
2782
2783		changed = TRUE;
2784		if (drmmode->delete_dp_12_displays) {
2785			RROutputDestroy(output->randr_output);
2786			xf86OutputDestroy(output);
2787			goto restart_destroy;
2788		}
2789	}
2790
2791	/* find new output ids we don't have outputs for */
2792	for (i = 0; i < mode_res->count_connectors; i++) {
2793		if (drmmode_find_output(pRADEONEnt->primary_scrn,
2794					mode_res->connectors[i],
2795					&num_dvi, &num_hdmi) ||
2796		    (pRADEONEnt->secondary_scrn &&
2797		     drmmode_find_output(pRADEONEnt->secondary_scrn,
2798					 mode_res->connectors[i],
2799					 &num_dvi, &num_hdmi)))
2800			continue;
2801
2802		if (drmmode_output_init(scrn, drmmode, mode_res, i, &num_dvi,
2803					&num_hdmi, 1) != 0)
2804			changed = TRUE;
2805	}
2806
2807	if (changed && dixPrivateKeyRegistered(rrPrivKey)) {
2808#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,2,0)
2809		RRSetChanged(xf86ScrnToScreen(scrn));
2810#else
2811		rrScrPrivPtr rrScrPriv = rrGetScrPriv(scrn->pScreen);
2812		rrScrPriv->changed = TRUE;
2813#endif
2814		RRTellChanged(xf86ScrnToScreen(scrn));
2815	}
2816
2817	drmModeFreeResources(mode_res);
2818out:
2819	RRGetInfo(xf86ScrnToScreen(scrn), TRUE);
2820}
2821#ifdef HAVE_LIBUDEV
2822static void
2823drmmode_handle_uevents(int fd, void *closure)
2824{
2825	drmmode_ptr drmmode = closure;
2826	ScrnInfoPtr scrn = drmmode->scrn;
2827	struct udev_device *dev;
2828	Bool received = FALSE;
2829	struct timeval tv = { 0, 0 };
2830	fd_set readfd;
2831
2832	FD_ZERO(&readfd);
2833	FD_SET(fd, &readfd);
2834
2835	while (select(fd + 1, &readfd, NULL, NULL, &tv) > 0 &&
2836	       FD_ISSET(fd, &readfd)) {
2837		/* select() ensured that this will not block */
2838		dev = udev_monitor_receive_device(drmmode->uevent_monitor);
2839		if (dev) {
2840			udev_device_unref(dev);
2841			received = TRUE;
2842		}
2843	}
2844
2845	if (received)
2846		radeon_mode_hotplug(scrn, drmmode);
2847}
2848#endif
2849
2850void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
2851{
2852#ifdef HAVE_LIBUDEV
2853	struct udev *u;
2854	struct udev_monitor *mon;
2855
2856	u = udev_new();
2857	if (!u)
2858		return;
2859	mon = udev_monitor_new_from_netlink(u, "udev");
2860	if (!mon) {
2861		udev_unref(u);
2862		return;
2863	}
2864
2865	if (udev_monitor_filter_add_match_subsystem_devtype(mon,
2866							    "drm",
2867							    "drm_minor") < 0 ||
2868	    udev_monitor_enable_receiving(mon) < 0) {
2869		udev_monitor_unref(mon);
2870		udev_unref(u);
2871		return;
2872	}
2873
2874	drmmode->uevent_handler =
2875		xf86AddGeneralHandler(udev_monitor_get_fd(mon),
2876				      drmmode_handle_uevents,
2877				      drmmode);
2878
2879	drmmode->uevent_monitor = mon;
2880#endif
2881}
2882
2883void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
2884{
2885#ifdef HAVE_LIBUDEV
2886	if (drmmode->uevent_handler) {
2887		struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor);
2888		xf86RemoveGeneralHandler(drmmode->uevent_handler);
2889
2890		udev_monitor_unref(drmmode->uevent_monitor);
2891		udev_unref(u);
2892	}
2893#endif
2894}
2895
2896Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
2897			uint32_t new_front_handle, uint64_t id, void *data,
2898			int ref_crtc_hw_id, radeon_drm_handler_proc handler,
2899			radeon_drm_abort_proc abort,
2900			enum drmmode_flip_sync flip_sync,
2901			uint32_t target_msc)
2902{
2903	RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
2904	RADEONInfoPtr info = RADEONPTR(scrn);
2905	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
2906	xf86CrtcPtr crtc = NULL;
2907	drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private;
2908	drmmode_ptr drmmode = drmmode_crtc->drmmode;
2909	unsigned int pitch;
2910	int i;
2911	uint32_t tiling_flags = 0;
2912	uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0;
2913	drmmode_flipdata_ptr flipdata;
2914	uintptr_t drm_queue_seq = 0;
2915
2916	if (info->allowColorTiling) {
2917		if (info->ChipFamily >= CHIP_FAMILY_R600)
2918			tiling_flags |= RADEON_TILING_MICRO;
2919		else
2920			tiling_flags |= RADEON_TILING_MACRO;
2921	}
2922
2923	pitch = RADEON_ALIGN(scrn->displayWidth, drmmode_get_pitch_align(scrn, info->pixel_bytes, tiling_flags)) *
2924		info->pixel_bytes;
2925	if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) {
2926		pitch = info->front_surface.level[0].pitch_bytes;
2927	}
2928
2929        flipdata = calloc(1, sizeof(drmmode_flipdata_rec));
2930        if (!flipdata) {
2931             xf86DrvMsg(scrn->scrnIndex, X_WARNING,
2932                        "flip queue: data alloc failed.\n");
2933             goto error;
2934        }
2935
2936	/*
2937	 * Create a new handle for the back buffer
2938	 */
2939	flipdata->old_fb_id = drmmode->fb_id;
2940	if (drmModeAddFB(drmmode->fd, scrn->virtualX, scrn->virtualY,
2941			 scrn->depth, scrn->bitsPerPixel, pitch,
2942			 new_front_handle, &drmmode->fb_id))
2943		goto error;
2944
2945	/*
2946	 * Queue flips on all enabled CRTCs
2947	 * Note that if/when we get per-CRTC buffers, we'll have to update this.
2948	 * Right now it assumes a single shared fb across all CRTCs, with the
2949	 * kernel fixing up the offset of each CRTC as necessary.
2950	 *
2951	 * Also, flips queued on disabled or incorrectly configured displays
2952	 * may never complete; this is a configuration error.
2953	 */
2954
2955        flipdata->event_data = data;
2956        flipdata->handler = handler;
2957        flipdata->abort = abort;
2958
2959	for (i = 0; i < config->num_crtc; i++) {
2960		crtc = config->crtc[i];
2961
2962		if (!crtc->enabled)
2963			continue;
2964
2965		flipdata->flip_count++;
2966		drmmode_crtc = crtc->driver_private;
2967
2968		/* Only the reference crtc will finally deliver its page flip
2969		 * completion event. All other crtc's events will be discarded.
2970		 */
2971		if (drmmode_crtc->hw_id == ref_crtc_hw_id)
2972			flipdata->fe_crtc = crtc;
2973
2974		drm_queue_seq = radeon_drm_queue_alloc(crtc, client, id,
2975						       flipdata,
2976						       drmmode_flip_handler,
2977						       drmmode_flip_abort);
2978		if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
2979			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
2980				   "Allocating DRM queue event entry failed.\n");
2981			goto error;
2982		}
2983
2984		if (drmmode_crtc->hw_id == ref_crtc_hw_id) {
2985			if (drmmode_page_flip_target_absolute(pRADEONEnt,
2986							      drmmode_crtc,
2987							      drmmode->fb_id,
2988							      flip_flags,
2989							      drm_queue_seq,
2990							      target_msc) != 0)
2991				goto flip_error;
2992		} else {
2993			if (drmmode_page_flip_target_relative(pRADEONEnt,
2994							      drmmode_crtc,
2995							      drmmode->fb_id,
2996							      flip_flags,
2997							      drm_queue_seq, 0) != 0)
2998				goto flip_error;
2999		}
3000
3001		drmmode_crtc->flip_pending = TRUE;
3002		drm_queue_seq = 0;
3003	}
3004
3005	if (flipdata->flip_count > 0)
3006		return TRUE;
3007
3008flip_error:
3009	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed: %s\n",
3010		   strerror(errno));
3011
3012error:
3013	if (flipdata && flipdata->flip_count <= 1 &&
3014	    drmmode->fb_id != flipdata->old_fb_id) {
3015		drmModeRmFB(drmmode->fd, drmmode->fb_id);
3016		drmmode->fb_id = flipdata->old_fb_id;
3017	}
3018
3019	if (drm_queue_seq)
3020		radeon_drm_abort_entry(drm_queue_seq);
3021	else if (crtc)
3022		drmmode_flip_abort(crtc, flipdata);
3023	else {
3024		abort(NULL, data);
3025		free(flipdata);
3026	}
3027
3028	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n",
3029		   strerror(errno));
3030	return FALSE;
3031}
3032