amdgpu_kms.c revision e49c54bc
1/*
2 * Copyright © 2009 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#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <errno.h>
32#include <sys/ioctl.h>
33/* Driver data structures */
34#include "amdgpu_drv.h"
35#include "amdgpu_bo_helper.h"
36#include "amdgpu_drm_queue.h"
37#include "amdgpu_glamor.h"
38#include "amdgpu_probe.h"
39#include "micmap.h"
40#include "mipointrst.h"
41
42#include "amdgpu_version.h"
43#include "shadow.h"
44#include <xf86Priv.h>
45
46#if HAVE_PRESENT_H
47#include <present.h>
48#endif
49
50/* DPMS */
51#ifdef HAVE_XEXTPROTO_71
52#include <X11/extensions/dpmsconst.h>
53#else
54#define DPMS_SERVER
55#include <X11/extensions/dpms.h>
56#endif
57
58#include <X11/extensions/damageproto.h>
59
60#include "amdgpu_bo_helper.h"
61#include "amdgpu_pixmap.h"
62
63#include <gbm.h>
64
65static DevPrivateKeyRec amdgpu_window_private_key;
66static DevScreenPrivateKeyRec amdgpu_client_private_key;
67DevScreenPrivateKeyRec amdgpu_device_private_key;
68
69static Atom amdgpu_vrr_atom;
70static Bool amdgpu_property_vectors_wrapped;
71static Bool restore_property_vector;
72static int (*saved_change_property) (ClientPtr client);
73static int (*saved_delete_property) (ClientPtr client);
74
75static Bool amdgpu_setup_kernel_mem(ScreenPtr pScreen);
76
77const OptionInfoRec AMDGPUOptions_KMS[] = {
78	{OPTION_ACCEL, "Accel", OPTV_BOOLEAN, {0}, FALSE},
79	{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
80	{OPTION_PAGE_FLIP, "EnablePageFlip", OPTV_BOOLEAN, {0}, FALSE},
81	{OPTION_SUBPIXEL_ORDER, "SubPixelOrder", OPTV_ANYSTR, {0}, FALSE},
82	{OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE},
83	{OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE},
84	{OPTION_DRI3, "DRI3", OPTV_BOOLEAN, {0}, FALSE},
85	{OPTION_DRI, "DRI", OPTV_INTEGER, {0}, FALSE},
86	{OPTION_SHADOW_PRIMARY, "ShadowPrimary", OPTV_BOOLEAN, {0}, FALSE},
87	{OPTION_TEAR_FREE, "TearFree", OPTV_BOOLEAN, {0}, FALSE},
88	{OPTION_DELETE_DP12, "DeleteUnusedDP12Displays", OPTV_BOOLEAN, {0}, FALSE},
89	{OPTION_VARIABLE_REFRESH, "VariableRefresh", OPTV_BOOLEAN, {0}, FALSE },
90	{OPTION_ASYNC_FLIP_SECONDARIES, "AsyncFlipSecondaries", OPTV_BOOLEAN, {0}, FALSE},
91	{-1, NULL, OPTV_NONE, {0}, FALSE}
92};
93
94const OptionInfoRec *AMDGPUOptionsWeak(void)
95{
96	return AMDGPUOptions_KMS;
97}
98
99static inline struct amdgpu_window_priv *get_window_priv(WindowPtr win) {
100	return dixLookupPrivate(&win->devPrivates, &amdgpu_window_private_key);
101}
102
103static void
104amdgpu_vrr_property_update(WindowPtr window, Bool variable_refresh)
105{
106	ScrnInfoPtr scrn = xf86ScreenToScrn(window->drawable.pScreen);
107	AMDGPUInfoPtr info = AMDGPUPTR(scrn);
108
109	get_window_priv(window)->variable_refresh = variable_refresh;
110
111	if (info->flip_window == window &&
112	    info->drmmode.present_flipping)
113		amdgpu_present_set_screen_vrr(scrn, variable_refresh);
114}
115
116/* Wrapper for xserver/dix/property.c:ProcChangeProperty */
117static int
118amdgpu_change_property(ClientPtr client)
119{
120	WindowPtr window;
121	int ret;
122
123	REQUEST(xChangePropertyReq);
124
125	client->requestVector[X_ChangeProperty] = saved_change_property;
126	ret = saved_change_property(client);
127
128	if (restore_property_vector)
129		return ret;
130
131	client->requestVector[X_ChangeProperty] = amdgpu_change_property;
132
133	if (ret != Success)
134		return ret;
135
136	ret = dixLookupWindow(&window, stuff->window, client, DixSetPropAccess);
137	if (ret != Success)
138		return ret;
139
140	if (stuff->property == amdgpu_vrr_atom &&
141	    xf86ScreenToScrn(window->drawable.pScreen)->PreInit ==
142	    AMDGPUPreInit_KMS && stuff->format == 32 && stuff->nUnits == 1) {
143		uint32_t *value = (uint32_t*)(stuff + 1);
144
145		amdgpu_vrr_property_update(window, *value != 0);
146	}
147
148	return ret;
149}
150
151/* Wrapper for xserver/dix/property.c:ProcDeleteProperty */
152static int
153amdgpu_delete_property(ClientPtr client)
154{
155	WindowPtr window;
156	int ret;
157
158	REQUEST(xDeletePropertyReq);
159
160	client->requestVector[X_DeleteProperty] = saved_delete_property;
161	ret = saved_delete_property(client);
162
163	if (restore_property_vector)
164		return ret;
165
166	client->requestVector[X_DeleteProperty] = amdgpu_delete_property;
167
168	if (ret != Success)
169		return ret;
170
171	ret = dixLookupWindow(&window, stuff->window, client, DixSetPropAccess);
172	if (ret != Success)
173		return ret;
174
175	if (stuff->property == amdgpu_vrr_atom &&
176	    xf86ScreenToScrn(window->drawable.pScreen)->PreInit ==
177	    AMDGPUPreInit_KMS)
178		amdgpu_vrr_property_update(window, FALSE);
179
180	return ret;
181}
182
183static void
184amdgpu_unwrap_property_requests(ScrnInfoPtr scrn)
185{
186	int i;
187
188	if (!amdgpu_property_vectors_wrapped)
189		return;
190
191	if (ProcVector[X_ChangeProperty] == amdgpu_change_property)
192		ProcVector[X_ChangeProperty] = saved_change_property;
193	else
194		restore_property_vector = TRUE;
195
196	if (ProcVector[X_DeleteProperty] == amdgpu_delete_property)
197		ProcVector[X_DeleteProperty] = saved_delete_property;
198	else
199		restore_property_vector = TRUE;
200
201	for (i = 0; i < currentMaxClients; i++) {
202		if (clients[i]->requestVector[X_ChangeProperty] ==
203		    amdgpu_change_property) {
204			clients[i]->requestVector[X_ChangeProperty] =
205				saved_change_property;
206		} else {
207			restore_property_vector = TRUE;
208		}
209
210		if (clients[i]->requestVector[X_DeleteProperty] ==
211		    amdgpu_delete_property) {
212			clients[i]->requestVector[X_DeleteProperty] =
213				saved_delete_property;
214		} else {
215			restore_property_vector = TRUE;
216		}
217	}
218
219	if (restore_property_vector) {
220		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
221			   "Couldn't unwrap some window property request vectors\n");
222	}
223
224	amdgpu_property_vectors_wrapped = FALSE;
225}
226
227extern _X_EXPORT int gAMDGPUEntityIndex;
228
229static int getAMDGPUEntityIndex(void)
230{
231	return gAMDGPUEntityIndex;
232}
233
234AMDGPUEntPtr AMDGPUEntPriv(ScrnInfoPtr pScrn)
235{
236	DevUnion *pPriv;
237	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
238	pPriv = xf86GetEntityPrivate(info->pEnt->index, getAMDGPUEntityIndex());
239	return pPriv->ptr;
240}
241
242/* Allocate our private AMDGPUInfoRec */
243static Bool AMDGPUGetRec(ScrnInfoPtr pScrn)
244{
245	if (pScrn->driverPrivate)
246		return TRUE;
247
248	pScrn->driverPrivate = xnfcalloc(sizeof(AMDGPUInfoRec), 1);
249	return TRUE;
250}
251
252/* Free our private AMDGPUInfoRec */
253static void AMDGPUFreeRec(ScrnInfoPtr pScrn)
254{
255	DevUnion *pPriv;
256	AMDGPUEntPtr pAMDGPUEnt;
257	AMDGPUInfoPtr info;
258	EntityInfoPtr pEnt;
259
260	if (!pScrn)
261		return;
262
263	pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
264	pPriv = xf86GetEntityPrivate(pEnt->index, gAMDGPUEntityIndex);
265	pAMDGPUEnt = pPriv->ptr;
266
267	info = AMDGPUPTR(pScrn);
268	if (info) {
269		pAMDGPUEnt->scrn[info->instance_id] = NULL;
270		pAMDGPUEnt->num_scrns--;
271		free(pScrn->driverPrivate);
272		pScrn->driverPrivate = NULL;
273	}
274
275	if (pAMDGPUEnt->fd > 0) {
276		DevUnion *pPriv;
277		AMDGPUEntPtr pAMDGPUEnt;
278		pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
279					     getAMDGPUEntityIndex());
280
281		pAMDGPUEnt = pPriv->ptr;
282		pAMDGPUEnt->fd_ref--;
283		if (!pAMDGPUEnt->fd_ref) {
284			amdgpu_unwrap_property_requests(pScrn);
285			amdgpu_device_deinitialize(pAMDGPUEnt->pDev);
286			amdgpu_kernel_close_fd(pAMDGPUEnt);
287			free(pAMDGPUEnt->busid);
288			free(pPriv->ptr);
289			pPriv->ptr = NULL;
290		}
291	}
292
293	free(pEnt);
294}
295
296Bool amdgpu_window_has_variable_refresh(WindowPtr win) {
297	struct amdgpu_window_priv *priv = get_window_priv(win);
298
299	return priv->variable_refresh;
300}
301
302static void *amdgpuShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset,
303				int mode, CARD32 * size, void *closure)
304{
305	ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
306	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
307	int stride;
308
309	stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
310	*size = stride;
311
312	return ((uint8_t *) info->front_buffer->cpu_ptr + row * stride + offset);
313}
314
315static void
316amdgpuUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
317{
318	shadowUpdatePacked(pScreen, pBuf);
319}
320
321static Bool
322callback_needs_flush(AMDGPUInfoPtr info, struct amdgpu_client_priv *client_priv)
323{
324	return (int)(client_priv->needs_flush - info->gpu_flushed) > 0;
325}
326
327static void
328amdgpu_event_callback(CallbackListPtr *list,
329		      pointer user_data, pointer call_data)
330{
331	EventInfoRec *eventinfo = call_data;
332	ScrnInfoPtr pScrn = user_data;
333	ScreenPtr pScreen = pScrn->pScreen;
334	struct amdgpu_client_priv *client_priv =
335		dixLookupScreenPrivate(&eventinfo->client->devPrivates,
336				       &amdgpu_client_private_key, pScreen);
337	struct amdgpu_client_priv *server_priv =
338		dixLookupScreenPrivate(&serverClient->devPrivates,
339				       &amdgpu_client_private_key, pScreen);
340	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
341	int i;
342
343	if (callback_needs_flush(info, client_priv) ||
344	    callback_needs_flush(info, server_priv))
345		return;
346
347	/* Don't let gpu_flushed get too far ahead of needs_flush, in order
348	 * to prevent false positives in callback_needs_flush()
349	 */
350	client_priv->needs_flush = info->gpu_flushed;
351	server_priv->needs_flush = info->gpu_flushed;
352
353	for (i = 0; i < eventinfo->count; i++) {
354		if (eventinfo->events[i].u.u.type == info->callback_event_type) {
355			client_priv->needs_flush++;
356			server_priv->needs_flush++;
357			return;
358		}
359	}
360}
361
362static void
363amdgpu_flush_callback(CallbackListPtr *list,
364		      pointer user_data, pointer call_data)
365{
366	ScrnInfoPtr pScrn = user_data;
367	ScreenPtr pScreen = pScrn->pScreen;
368	ClientPtr client = call_data ? call_data : serverClient;
369	struct amdgpu_client_priv *client_priv =
370		dixLookupScreenPrivate(&client->devPrivates,
371				       &amdgpu_client_private_key, pScreen);
372	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
373
374	if (pScrn->vtSema && callback_needs_flush(info, client_priv))
375		amdgpu_glamor_flush(pScrn);
376}
377
378static Bool AMDGPUCreateScreenResources_KMS(ScreenPtr pScreen)
379{
380	ExtensionEntry *damage_ext;
381	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
382	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
383	PixmapPtr pixmap;
384
385	pScreen->CreateScreenResources = info->CreateScreenResources;
386	if (!(*pScreen->CreateScreenResources) (pScreen))
387		return FALSE;
388	pScreen->CreateScreenResources = AMDGPUCreateScreenResources_KMS;
389
390	/* Set the RandR primary output if Xorg hasn't */
391	if (dixPrivateKeyRegistered(rrPrivKey)) {
392		rrScrPrivPtr rrScrPriv = rrGetScrPriv(pScreen);
393
394		if (!pScreen->isGPU && !rrScrPriv->primaryOutput) {
395			xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
396
397			rrScrPriv->primaryOutput = xf86_config->output[0]->randr_output;
398			RROutputChanged(rrScrPriv->primaryOutput, FALSE);
399			rrScrPriv->layoutChanged = TRUE;
400		}
401
402		drmmode_uevent_init(pScrn, &info->drmmode);
403	}
404
405	if (!drmmode_set_desired_modes(pScrn, &info->drmmode, pScreen->isGPU))
406		return FALSE;
407
408	if (info->shadow_fb) {
409		pixmap = pScreen->GetScreenPixmap(pScreen);
410
411		if (!shadowAdd(pScreen, pixmap, amdgpuUpdatePacked,
412			       amdgpuShadowWindow, 0, NULL))
413			return FALSE;
414	}
415
416	if (info->dri2.enabled || info->use_glamor) {
417		if (info->front_buffer) {
418			PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
419
420			if (!amdgpu_set_pixmap_bo(pPix, info->front_buffer))
421				return FALSE;
422		}
423	}
424
425	if (info->use_glamor)
426		amdgpu_glamor_create_screen_resources(pScreen);
427
428	info->callback_event_type = -1;
429	if (!pScreen->isGPU && (damage_ext = CheckExtension("DAMAGE"))) {
430		info->callback_event_type = damage_ext->eventBase + XDamageNotify;
431
432		if (!AddCallback(&FlushCallback, amdgpu_flush_callback, pScrn))
433			return FALSE;
434
435		if (!AddCallback(&EventCallback, amdgpu_event_callback, pScrn)) {
436			DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn);
437			return FALSE;
438		}
439
440		if (!dixRegisterScreenPrivateKey(&amdgpu_client_private_key, pScreen,
441						 PRIVATE_CLIENT, sizeof(struct amdgpu_client_priv))) {
442			DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn);
443			DeleteCallback(&EventCallback, amdgpu_event_callback, pScrn);
444			return FALSE;
445		}
446	}
447
448	if (info->vrr_support &&
449	    !dixRegisterPrivateKey(&amdgpu_window_private_key,
450				   PRIVATE_WINDOW,
451				   sizeof(struct amdgpu_window_priv)))
452		return FALSE;
453
454	return TRUE;
455}
456
457static Bool
458amdgpu_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents)
459{
460	if (xf86_crtc->scrn->is_gpu) {
461		extents->x1 -= xf86_crtc->x;
462		extents->y1 -= xf86_crtc->y;
463		extents->x2 -= xf86_crtc->x;
464		extents->y2 -= xf86_crtc->y;
465	} else {
466		extents->x1 -= xf86_crtc->filter_width >> 1;
467		extents->x2 += xf86_crtc->filter_width >> 1;
468		extents->y1 -= xf86_crtc->filter_height >> 1;
469		extents->y2 += xf86_crtc->filter_height >> 1;
470		pixman_f_transform_bounds(&xf86_crtc->f_framebuffer_to_crtc, extents);
471	}
472
473	extents->x1 = max(extents->x1, 0);
474	extents->y1 = max(extents->y1, 0);
475	extents->x2 = min(extents->x2, xf86_crtc->mode.HDisplay);
476	extents->y2 = min(extents->y2, xf86_crtc->mode.VDisplay);
477
478	return (extents->x1 < extents->x2 && extents->y1 < extents->y2);
479}
480
481static RegionPtr
482transform_region(RegionPtr region, struct pict_f_transform *transform,
483		 int w, int h)
484{
485	BoxPtr boxes = RegionRects(region);
486	int nboxes = RegionNumRects(region);
487	xRectanglePtr rects = malloc(nboxes * sizeof(*rects));
488	RegionPtr transformed;
489	int nrects = 0;
490	BoxRec box;
491	int i;
492
493	for (i = 0; i < nboxes; i++) {
494		box.x1 = boxes[i].x1;
495		box.x2 = boxes[i].x2;
496		box.y1 = boxes[i].y1;
497		box.y2 = boxes[i].y2;
498		pixman_f_transform_bounds(transform, &box);
499
500		box.x1 = max(box.x1, 0);
501		box.y1 = max(box.y1, 0);
502		box.x2 = min(box.x2, w);
503		box.y2 = min(box.y2, h);
504		if (box.x1 >= box.x2 || box.y1 >= box.y2)
505			continue;
506
507		rects[nrects].x = box.x1;
508		rects[nrects].y = box.y1;
509		rects[nrects].width = box.x2 - box.x1;
510		rects[nrects].height = box.y2 - box.y1;
511		nrects++;
512	}
513
514	transformed = RegionFromRects(nrects, rects, CT_UNSORTED);
515	free(rects);
516	return transformed;
517}
518
519static void
520amdgpu_sync_scanout_pixmaps(xf86CrtcPtr xf86_crtc, RegionPtr new_region,
521							int scanout_id)
522{
523	drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
524	DrawablePtr dst = &drmmode_crtc->scanout[scanout_id]->drawable;
525	DrawablePtr src = &drmmode_crtc->scanout[scanout_id ^ 1]->drawable;
526	RegionPtr last_region = &drmmode_crtc->scanout_last_region;
527	ScrnInfoPtr scrn = xf86_crtc->scrn;
528	ScreenPtr pScreen = scrn->pScreen;
529	RegionRec remaining;
530	RegionPtr sync_region = NULL;
531	BoxRec extents;
532	GCPtr gc;
533
534	if (RegionNil(last_region))
535		return;
536
537	RegionNull(&remaining);
538	RegionSubtract(&remaining, last_region, new_region);
539	if (RegionNil(&remaining))
540		goto uninit;
541
542	extents = *RegionExtents(&remaining);
543	if (!amdgpu_scanout_extents_intersect(xf86_crtc, &extents))
544		goto uninit;
545
546	if (xf86_crtc->driverIsPerformingTransform) {
547		sync_region = transform_region(&remaining,
548					       &xf86_crtc->f_framebuffer_to_crtc,
549					       dst->width, dst->height);
550	} else {
551		sync_region = RegionDuplicate(&remaining);
552		RegionTranslate(sync_region, -xf86_crtc->x, -xf86_crtc->y);
553	}
554
555	gc = GetScratchGC(dst->depth, pScreen);
556	if (gc) {
557		gc->funcs->ChangeClip(gc, CT_REGION, sync_region, 0);
558		ValidateGC(dst, gc);
559		sync_region = NULL;
560		gc->ops->CopyArea(src, dst, gc, 0, 0, dst->width, dst->height, 0, 0);
561		FreeScratchGC(gc);
562	}
563
564 uninit:
565	if (sync_region)
566		RegionDestroy(sync_region);
567	RegionUninit(&remaining);
568}
569
570static void
571amdgpu_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data)
572{
573	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(crtc->scrn);
574	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
575	struct drmmode_fb *fb = event_data;
576
577	drmmode_crtc->scanout_update_pending = 0;
578
579	if (drmmode_crtc->flip_pending == fb) {
580		drmmode_fb_reference(pAMDGPUEnt->fd, &drmmode_crtc->flip_pending,
581				     NULL);
582	}
583}
584
585static void
586amdgpu_scanout_flip_handler(xf86CrtcPtr crtc, uint32_t msc, uint64_t usec,
587			    void *event_data)
588{
589	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(crtc->scrn);
590	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
591	struct drmmode_fb *fb = event_data;
592
593	drmmode_fb_reference(pAMDGPUEnt->fd, &drmmode_crtc->fb, fb);
594	amdgpu_scanout_flip_abort(crtc, event_data);
595}
596
597
598static RegionPtr
599dirty_region(PixmapDirtyUpdatePtr dirty)
600{
601	RegionPtr damageregion = DamageRegion(dirty->damage);
602	RegionPtr dstregion;
603
604#ifdef HAS_DIRTYTRACKING_ROTATION
605	if (dirty->rotation != RR_Rotate_0) {
606		dstregion = transform_region(damageregion,
607					     &dirty->f_inverse,
608					     dirty->secondary_dst->drawable.width,
609					     dirty->secondary_dst->drawable.height);
610	} else
611#endif
612	{
613		RegionRec pixregion;
614
615		dstregion = RegionDuplicate(damageregion);
616		RegionTranslate(dstregion, -dirty->x, -dirty->y);
617		PixmapRegionInit(&pixregion, dirty->secondary_dst);
618		RegionIntersect(dstregion, dstregion, &pixregion);
619		RegionUninit(&pixregion);
620	}
621
622	return dstregion;
623}
624
625static void
626redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region)
627{
628	ScrnInfoPtr src_scrn =
629		xf86ScreenToScrn(amdgpu_dirty_src_drawable(dirty)->pScreen);
630
631	if (RegionNil(region))
632		goto out;
633
634	if (dirty->secondary_dst->primary_pixmap)
635		DamageRegionAppend(&dirty->secondary_dst->drawable, region);
636
637#ifdef HAS_DIRTYTRACKING_ROTATION
638	PixmapSyncDirtyHelper(dirty);
639#else
640	PixmapSyncDirtyHelper(dirty, region);
641#endif
642
643	amdgpu_glamor_flush(src_scrn);
644	if (dirty->secondary_dst->primary_pixmap)
645		DamageRegionProcessPending(&dirty->secondary_dst->drawable);
646
647out:
648	DamageEmpty(dirty->damage);
649}
650
651static void
652amdgpu_prime_scanout_update_abort(xf86CrtcPtr crtc, void *event_data)
653{
654	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
655
656	drmmode_crtc->scanout_update_pending = 0;
657}
658
659void
660amdgpu_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
661{
662	ScreenPtr primary_screen = amdgpu_dirty_primary(dirty);
663	PixmapDirtyUpdatePtr ent;
664	RegionPtr region;
665
666	xorg_list_for_each_entry(ent, &primary_screen->pixmap_dirty_list, ent) {
667		if (!amdgpu_dirty_src_equals(dirty, ent->secondary_dst))
668			continue;
669
670		region = dirty_region(ent);
671		redisplay_dirty(ent, region);
672		RegionDestroy(region);
673	}
674}
675
676
677#if HAS_SYNC_SHARED_PIXMAP
678
679static Bool
680primary_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
681{
682	ScreenPtr primary_screen = amdgpu_dirty_primary(dirty);
683
684	return primary_screen->SyncSharedPixmap != NULL;
685}
686
687static Bool
688secondary_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
689{
690	ScreenPtr secondary_screen = dirty->secondary_dst->drawable.pScreen;
691
692	return secondary_screen->SyncSharedPixmap != NULL;
693}
694
695static void
696call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
697{
698	ScreenPtr primary_screen = amdgpu_dirty_primary(dirty);
699
700	primary_screen->SyncSharedPixmap(dirty);
701}
702
703#else /* !HAS_SYNC_SHARED_PIXMAP */
704
705static Bool
706primary_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
707{
708	ScrnInfoPtr primary_scrn = xf86ScreenToScrn(amdgpu_dirty_primary(dirty));
709
710	return primary_scrn->driverName == scrn->driverName;
711}
712
713static Bool
714secondary_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
715{
716	ScrnInfoPtr secondary_scrn = xf86ScreenToScrn(dirty->secondary_dst->drawable.pScreen);
717
718	return secondary_scrn->driverName == scrn->driverName;
719}
720
721static void
722call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
723{
724	amdgpu_sync_shared_pixmap(dirty);
725}
726
727#endif /* HAS_SYNC_SHARED_PIXMAPS */
728
729
730static xf86CrtcPtr
731amdgpu_prime_dirty_to_crtc(PixmapDirtyUpdatePtr dirty)
732{
733	ScreenPtr screen = dirty->secondary_dst->drawable.pScreen;
734	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
735	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
736	int c;
737
738	/* Find the CRTC which is scanning out from this secondary pixmap */
739	for (c = 0; c < xf86_config->num_crtc; c++) {
740		xf86CrtcPtr xf86_crtc = xf86_config->crtc[c];
741		drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
742
743		if (amdgpu_dirty_src_equals(dirty, drmmode_crtc->prime_scanout_pixmap))
744			return xf86_crtc;
745	}
746
747	return NULL;
748}
749
750static Bool
751amdgpu_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
752{
753	ScrnInfoPtr scrn = crtc->scrn;
754	ScreenPtr screen = scrn->pScreen;
755	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
756	PixmapDirtyUpdatePtr dirty;
757	Bool ret = FALSE;
758
759	xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
760		if (amdgpu_dirty_src_equals(dirty, drmmode_crtc->prime_scanout_pixmap)) {
761			RegionPtr region;
762
763			if (primary_has_sync_shared_pixmap(scrn, dirty))
764				call_sync_shared_pixmap(dirty);
765
766			region = dirty_region(dirty);
767			if (RegionNil(region))
768				goto destroy;
769
770			if (drmmode_crtc->tear_free) {
771				RegionTranslate(region, crtc->x, crtc->y);
772				amdgpu_sync_scanout_pixmaps(crtc, region, scanout_id);
773				amdgpu_glamor_flush(scrn);
774				RegionCopy(&drmmode_crtc->scanout_last_region, region);
775				RegionTranslate(region, -crtc->x, -crtc->y);
776				dirty->secondary_dst = drmmode_crtc->scanout[scanout_id];
777			}
778
779			redisplay_dirty(dirty, region);
780			ret = TRUE;
781		destroy:
782			RegionDestroy(region);
783			break;
784		}
785	}
786
787	return ret;
788}
789
790static void
791amdgpu_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
792				     void *event_data)
793{
794	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
795
796	amdgpu_prime_scanout_do_update(crtc, 0);
797	drmmode_crtc->scanout_update_pending = 0;
798}
799
800static void
801amdgpu_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
802{
803	ScreenPtr screen = dirty->secondary_dst->drawable.pScreen;
804	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
805	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
806	xf86CrtcPtr xf86_crtc = amdgpu_prime_dirty_to_crtc(dirty);
807	drmmode_crtc_private_ptr drmmode_crtc;
808	uintptr_t drm_queue_seq;
809
810	if (!xf86_crtc || !xf86_crtc->enabled)
811		return;
812
813	drmmode_crtc = xf86_crtc->driver_private;
814	if (drmmode_crtc->scanout_update_pending ||
815	    !drmmode_crtc->scanout[drmmode_crtc->scanout_id] ||
816	    drmmode_crtc->dpms_mode != DPMSModeOn)
817		return;
818
819	drm_queue_seq = amdgpu_drm_queue_alloc(xf86_crtc,
820					       AMDGPU_DRM_QUEUE_CLIENT_DEFAULT,
821					       AMDGPU_DRM_QUEUE_ID_DEFAULT, NULL,
822					       amdgpu_prime_scanout_update_handler,
823					       amdgpu_prime_scanout_update_abort,
824					       FALSE);
825	if (drm_queue_seq == AMDGPU_DRM_QUEUE_ERROR) {
826		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
827			   "amdgpu_drm_queue_alloc failed for PRIME update\n");
828		amdgpu_prime_scanout_update_handler(xf86_crtc, 0, 0, NULL);
829		return;
830	}
831
832	drmmode_crtc->scanout_update_pending = drm_queue_seq;
833
834	if (!drmmode_wait_vblank(xf86_crtc, DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT,
835				 1, drm_queue_seq, NULL, NULL)) {
836		if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_VBLANK_FAILED)) {
837			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
838				   "drmmode_wait_vblank failed for PRIME update: %s\n",
839				   strerror(errno));
840			drmmode_crtc->scanout_status |= DRMMODE_SCANOUT_VBLANK_FAILED;
841		}
842
843		drmmode_crtc->drmmode->event_context.vblank_handler(pAMDGPUEnt->fd,
844								    0, 0, 0,
845								    (void*)drm_queue_seq);
846		drmmode_crtc->wait_flip_nesting_level++;
847		amdgpu_drm_queue_handle_deferred(xf86_crtc);
848		return;
849	}
850
851	if (drmmode_crtc->scanout_status ==
852	    (DRMMODE_SCANOUT_FLIP_FAILED | DRMMODE_SCANOUT_VBLANK_FAILED)) {
853		/* The page flip and vblank ioctls failed before, but the vblank
854		 * ioctl is working again, so we can try re-enabling TearFree
855		 */
856		xf86_crtc->funcs->set_mode_major(xf86_crtc, &xf86_crtc->mode,
857						 xf86_crtc->rotation,
858						 xf86_crtc->x, xf86_crtc->y);
859	}
860
861	drmmode_crtc->scanout_status &= ~DRMMODE_SCANOUT_VBLANK_FAILED;
862}
863
864static void
865amdgpu_prime_scanout_flip(PixmapDirtyUpdatePtr ent)
866{
867	ScreenPtr screen = ent->secondary_dst->drawable.pScreen;
868	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
869	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
870	xf86CrtcPtr crtc = amdgpu_prime_dirty_to_crtc(ent);
871	drmmode_crtc_private_ptr drmmode_crtc;
872	uintptr_t drm_queue_seq;
873	unsigned scanout_id;
874	struct drmmode_fb *fb;
875
876	if (!crtc || !crtc->enabled)
877		return;
878
879	drmmode_crtc = crtc->driver_private;
880	scanout_id = drmmode_crtc->scanout_id ^ 1;
881	if (drmmode_crtc->scanout_update_pending ||
882	    !drmmode_crtc->scanout[scanout_id] ||
883	    drmmode_crtc->dpms_mode != DPMSModeOn)
884		return;
885
886	if (!amdgpu_prime_scanout_do_update(crtc, scanout_id))
887		return;
888
889	fb = amdgpu_pixmap_get_fb(drmmode_crtc->scanout[scanout_id]);
890	if (!fb) {
891		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
892			   "Failed to get FB for PRIME flip.\n");
893		return;
894	}
895
896	drm_queue_seq = amdgpu_drm_queue_alloc(crtc,
897					       AMDGPU_DRM_QUEUE_CLIENT_DEFAULT,
898					       AMDGPU_DRM_QUEUE_ID_DEFAULT, fb,
899					       amdgpu_scanout_flip_handler,
900					       amdgpu_scanout_flip_abort, TRUE);
901	if (drm_queue_seq == AMDGPU_DRM_QUEUE_ERROR) {
902		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
903			   "Allocating DRM event queue entry failed for PRIME flip.\n");
904		return;
905	}
906
907	if (drmmode_page_flip_target_relative(pAMDGPUEnt, drmmode_crtc,
908					      fb->handle, 0, drm_queue_seq, 1)
909	    != 0) {
910		if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED)) {
911			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
912				   "flip queue failed in %s: %s, TearFree inactive\n",
913				   __func__, strerror(errno));
914			drmmode_crtc->scanout_status |= DRMMODE_SCANOUT_FLIP_FAILED;
915		}
916
917		amdgpu_drm_abort_entry(drm_queue_seq);
918		return;
919	}
920
921	if (drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED) {
922		xf86DrvMsg(scrn->scrnIndex, X_INFO, "TearFree active again\n");
923		drmmode_crtc->scanout_status &= ~DRMMODE_SCANOUT_FLIP_FAILED;
924	}
925
926	drmmode_crtc->scanout_id = scanout_id;
927	drmmode_crtc->scanout_update_pending = drm_queue_seq;
928	drmmode_fb_reference(pAMDGPUEnt->fd, &drmmode_crtc->flip_pending, fb);
929}
930
931static void
932amdgpu_dirty_update(ScrnInfoPtr scrn)
933{
934	ScreenPtr screen = scrn->pScreen;
935	PixmapDirtyUpdatePtr ent;
936	RegionPtr region;
937
938	xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
939		if (screen->isGPU) {
940			PixmapDirtyUpdatePtr region_ent = ent;
941
942			if (primary_has_sync_shared_pixmap(scrn, ent)) {
943				ScreenPtr primary_screen = amdgpu_dirty_primary(ent);
944
945				xorg_list_for_each_entry(region_ent, &primary_screen->pixmap_dirty_list, ent) {
946					if (amdgpu_dirty_src_equals(ent, region_ent->secondary_dst))
947						break;
948				}
949			}
950
951			region = dirty_region(region_ent);
952
953			if (RegionNotEmpty(region)) {
954				xf86CrtcPtr crtc = amdgpu_prime_dirty_to_crtc(ent);
955				drmmode_crtc_private_ptr drmmode_crtc = NULL;
956
957				if (crtc)
958					drmmode_crtc = crtc->driver_private;
959
960				if (drmmode_crtc && drmmode_crtc->tear_free)
961					amdgpu_prime_scanout_flip(ent);
962				else
963					amdgpu_prime_scanout_update(ent);
964			} else {
965				DamageEmpty(region_ent->damage);
966			}
967
968			RegionDestroy(region);
969		} else {
970			if (secondary_has_sync_shared_pixmap(scrn, ent))
971				continue;
972
973			region = dirty_region(ent);
974			redisplay_dirty(ent, region);
975			RegionDestroy(region);
976		}
977	}
978}
979
980static void
981amdgpuSourceValidate(DrawablePtr draw, int x, int y, int w, int h,
982		     unsigned int subWindowMode)
983{
984}
985
986Bool
987amdgpu_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id,
988			 PixmapPtr src_pix, BoxRec extents)
989{
990	drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
991	RegionRec region = { .extents = extents, .data = NULL };
992	ScrnInfoPtr scrn = xf86_crtc->scrn;
993	ScreenPtr pScreen = scrn->pScreen;
994	DrawablePtr pDraw;
995
996	if (!xf86_crtc->enabled ||
997	    !drmmode_crtc->scanout[scanout_id] ||
998	    extents.x1 >= extents.x2 || extents.y1 >= extents.y2)
999		return FALSE;
1000
1001	pDraw = &drmmode_crtc->scanout[scanout_id]->drawable;
1002	if (!amdgpu_scanout_extents_intersect(xf86_crtc, &extents))
1003		return FALSE;
1004
1005	if (drmmode_crtc->tear_free) {
1006		amdgpu_sync_scanout_pixmaps(xf86_crtc, &region, scanout_id);
1007		RegionCopy(&drmmode_crtc->scanout_last_region, &region);
1008	}
1009
1010	if (xf86_crtc->driverIsPerformingTransform) {
1011		SourceValidateProcPtr SourceValidate = pScreen->SourceValidate;
1012		PictFormatPtr format = PictureWindowFormat(pScreen->root);
1013		int error;
1014		PicturePtr src, dst;
1015
1016		src = CreatePicture(None, &src_pix->drawable, format, 0L, NULL,
1017				    serverClient, &error);
1018		if (!src) {
1019			ErrorF("Failed to create source picture for transformed scanout "
1020			       "update\n");
1021			goto out;
1022		}
1023
1024		dst = CreatePicture(None, pDraw, format, 0L, NULL, serverClient, &error);
1025		if (!dst) {
1026			ErrorF("Failed to create destination picture for transformed scanout "
1027			       "update\n");
1028			goto free_src;
1029		}
1030		error = SetPictureTransform(src, &xf86_crtc->crtc_to_framebuffer);
1031		if (error) {
1032			ErrorF("SetPictureTransform failed for transformed scanout "
1033			       "update\n");
1034			goto free_dst;
1035		}
1036
1037		if (xf86_crtc->filter)
1038			SetPicturePictFilter(src, xf86_crtc->filter, xf86_crtc->params,
1039					     xf86_crtc->nparams);
1040
1041		pScreen->SourceValidate = amdgpuSourceValidate;
1042		CompositePicture(PictOpSrc,
1043				 src, NULL, dst,
1044				 extents.x1, extents.y1, 0, 0, extents.x1,
1045				 extents.y1, extents.x2 - extents.x1,
1046				 extents.y2 - extents.y1);
1047		pScreen->SourceValidate = SourceValidate;
1048
1049 free_dst:
1050		FreePicture(dst, None);
1051 free_src:
1052		FreePicture(src, None);
1053	} else
1054 out:
1055	{
1056		GCPtr gc = GetScratchGC(pDraw->depth, pScreen);
1057
1058		ValidateGC(pDraw, gc);
1059		(*gc->ops->CopyArea)(&src_pix->drawable, pDraw, gc,
1060				     xf86_crtc->x + extents.x1, xf86_crtc->y + extents.y1,
1061				     extents.x2 - extents.x1, extents.y2 - extents.y1,
1062				     extents.x1, extents.y1);
1063		FreeScratchGC(gc);
1064	}
1065
1066	return TRUE;
1067}
1068
1069static void
1070amdgpu_scanout_update_abort(xf86CrtcPtr crtc, void *event_data)
1071{
1072	drmmode_crtc_private_ptr drmmode_crtc = event_data;
1073
1074	drmmode_crtc->scanout_update_pending = 0;
1075}
1076
1077static void
1078amdgpu_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
1079							  void *event_data)
1080{
1081	drmmode_crtc_private_ptr drmmode_crtc = event_data;
1082	ScreenPtr screen = crtc->scrn->pScreen;
1083	RegionPtr region = DamageRegion(drmmode_crtc->scanout_damage);
1084
1085	if (crtc->enabled &&
1086	    !drmmode_crtc->flip_pending &&
1087	    drmmode_crtc->dpms_mode == DPMSModeOn) {
1088		if (amdgpu_scanout_do_update(crtc, drmmode_crtc->scanout_id,
1089					     screen->GetWindowPixmap(screen->root),
1090					     region->extents)) {
1091			amdgpu_glamor_flush(crtc->scrn);
1092			RegionEmpty(region);
1093		}
1094	}
1095
1096	amdgpu_scanout_update_abort(crtc, event_data);
1097}
1098
1099static void
1100amdgpu_scanout_update(xf86CrtcPtr xf86_crtc)
1101{
1102	drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
1103	ScrnInfoPtr scrn = xf86_crtc->scrn;
1104	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
1105	uintptr_t drm_queue_seq;
1106	DamagePtr pDamage;
1107	RegionPtr pRegion;
1108	BoxRec extents;
1109
1110	if (!xf86_crtc->enabled ||
1111	    drmmode_crtc->scanout_update_pending ||
1112	    drmmode_crtc->flip_pending ||
1113	    drmmode_crtc->dpms_mode != DPMSModeOn)
1114		return;
1115
1116	pDamage = drmmode_crtc->scanout_damage;
1117	if (!pDamage)
1118		return;
1119
1120	pRegion = DamageRegion(pDamage);
1121	if (!RegionNotEmpty(pRegion))
1122		return;
1123
1124	extents = *RegionExtents(pRegion);
1125	if (!amdgpu_scanout_extents_intersect(xf86_crtc, &extents)) {
1126		RegionEmpty(pRegion);
1127		return;
1128	}
1129
1130	drm_queue_seq = amdgpu_drm_queue_alloc(xf86_crtc,
1131					       AMDGPU_DRM_QUEUE_CLIENT_DEFAULT,
1132					       AMDGPU_DRM_QUEUE_ID_DEFAULT,
1133					       drmmode_crtc,
1134					       amdgpu_scanout_update_handler,
1135					       amdgpu_scanout_update_abort,
1136					       FALSE);
1137	if (drm_queue_seq == AMDGPU_DRM_QUEUE_ERROR) {
1138		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1139			   "amdgpu_drm_queue_alloc failed for scanout update\n");
1140		amdgpu_scanout_update_handler(xf86_crtc, 0, 0, drmmode_crtc);
1141		return;
1142	}
1143
1144	drmmode_crtc->scanout_update_pending = drm_queue_seq;
1145
1146	if (!drmmode_wait_vblank(xf86_crtc, DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT,
1147				 1, drm_queue_seq, NULL, NULL)) {
1148		if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_VBLANK_FAILED)) {
1149			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1150				   "drmmode_wait_vblank failed for scanout update: %s\n",
1151				   strerror(errno));
1152			drmmode_crtc->scanout_status |= DRMMODE_SCANOUT_VBLANK_FAILED;
1153		}
1154
1155		drmmode_crtc->drmmode->event_context.vblank_handler(pAMDGPUEnt->fd,
1156								    0, 0, 0,
1157								    (void*)drm_queue_seq);
1158		drmmode_crtc->wait_flip_nesting_level++;
1159		amdgpu_drm_queue_handle_deferred(xf86_crtc);
1160		return;
1161	}
1162
1163	if (drmmode_crtc->scanout_status ==
1164	    (DRMMODE_SCANOUT_FLIP_FAILED | DRMMODE_SCANOUT_VBLANK_FAILED)) {
1165		/* The page flip and vblank ioctls failed before, but the vblank
1166		 * ioctl is working again, so we can try re-enabling TearFree
1167		 */
1168		xf86_crtc->funcs->set_mode_major(xf86_crtc, &xf86_crtc->mode,
1169						 xf86_crtc->rotation,
1170						 xf86_crtc->x, xf86_crtc->y);
1171	}
1172
1173	drmmode_crtc->scanout_status &= ~DRMMODE_SCANOUT_VBLANK_FAILED;
1174}
1175
1176static void
1177amdgpu_scanout_flip(ScreenPtr pScreen, AMDGPUInfoPtr info,
1178					xf86CrtcPtr xf86_crtc)
1179{
1180	drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
1181	RegionPtr region = DamageRegion(drmmode_crtc->scanout_damage);
1182	ScrnInfoPtr scrn = xf86_crtc->scrn;
1183	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
1184	uintptr_t drm_queue_seq;
1185	unsigned scanout_id;
1186	struct drmmode_fb *fb;
1187
1188	if (drmmode_crtc->scanout_update_pending ||
1189	    drmmode_crtc->flip_pending ||
1190	    drmmode_crtc->dpms_mode != DPMSModeOn)
1191		return;
1192
1193	scanout_id = drmmode_crtc->scanout_id ^ 1;
1194	if (!amdgpu_scanout_do_update(xf86_crtc, scanout_id,
1195				      pScreen->GetWindowPixmap(pScreen->root),
1196				      region->extents))
1197		return;
1198
1199	amdgpu_glamor_flush(scrn);
1200	RegionEmpty(region);
1201
1202	fb = amdgpu_pixmap_get_fb(drmmode_crtc->scanout[scanout_id]);
1203	if (!fb) {
1204		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1205			   "Failed to get FB for scanout flip.\n");
1206		return;
1207	}
1208
1209	drm_queue_seq = amdgpu_drm_queue_alloc(xf86_crtc,
1210					       AMDGPU_DRM_QUEUE_CLIENT_DEFAULT,
1211					       AMDGPU_DRM_QUEUE_ID_DEFAULT, fb,
1212					       amdgpu_scanout_flip_handler,
1213					       amdgpu_scanout_flip_abort, TRUE);
1214	if (drm_queue_seq == AMDGPU_DRM_QUEUE_ERROR) {
1215		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1216			   "Allocating DRM event queue entry failed.\n");
1217		return;
1218	}
1219
1220	if (drmmode_page_flip_target_relative(pAMDGPUEnt, drmmode_crtc,
1221					      fb->handle, 0, drm_queue_seq, 1)
1222	    != 0) {
1223		if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED)) {
1224			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1225				   "flip queue failed in %s: %s, TearFree inactive\n",
1226				   __func__, strerror(errno));
1227			drmmode_crtc->scanout_status |= DRMMODE_SCANOUT_FLIP_FAILED;
1228		}
1229
1230		amdgpu_drm_abort_entry(drm_queue_seq);
1231		RegionCopy(DamageRegion(drmmode_crtc->scanout_damage),
1232			   &drmmode_crtc->scanout_last_region);
1233		RegionEmpty(&drmmode_crtc->scanout_last_region);
1234		amdgpu_scanout_update(xf86_crtc);
1235		drmmode_crtc_scanout_destroy(&drmmode_crtc->scanout[scanout_id]);
1236		drmmode_crtc->tear_free = FALSE;
1237		return;
1238	}
1239
1240	if (drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED) {
1241		xf86DrvMsg(scrn->scrnIndex, X_INFO, "TearFree active again\n");
1242		drmmode_crtc->scanout_status &= ~DRMMODE_SCANOUT_FLIP_FAILED;
1243	}
1244
1245	drmmode_crtc->scanout_id = scanout_id;
1246	drmmode_crtc->scanout_update_pending = drm_queue_seq;
1247	drmmode_fb_reference(pAMDGPUEnt->fd, &drmmode_crtc->flip_pending, fb);
1248}
1249
1250static void AMDGPUBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
1251{
1252	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1253	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
1254	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1255	int c;
1256
1257	pScreen->BlockHandler = info->BlockHandler;
1258	(*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
1259	pScreen->BlockHandler = AMDGPUBlockHandler_KMS;
1260
1261	if (!xf86ScreenToScrn(amdgpu_primary_screen(pScreen))->vtSema)
1262		return;
1263
1264	if (!pScreen->isGPU)
1265	{
1266		for (c = 0; c < xf86_config->num_crtc; c++) {
1267			xf86CrtcPtr crtc = xf86_config->crtc[c];
1268			drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1269
1270			if (drmmode_crtc->rotate)
1271				continue;
1272
1273			if (drmmode_crtc->tear_free)
1274				amdgpu_scanout_flip(pScreen, info, crtc);
1275			else if (drmmode_crtc->scanout[drmmode_crtc->scanout_id])
1276				amdgpu_scanout_update(crtc);
1277		}
1278	}
1279
1280#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,19,0,0,0)
1281	if (info->use_glamor)
1282		amdgpu_glamor_flush(pScrn);
1283#endif
1284
1285	amdgpu_dirty_update(pScrn);
1286}
1287
1288/* This is called by AMDGPUPreInit to set up the default visual */
1289static Bool AMDGPUPreInitVisual(ScrnInfoPtr pScrn)
1290{
1291	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
1292
1293	if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb))
1294		return FALSE;
1295
1296	switch (pScrn->depth) {
1297	case 8:
1298	case 15:
1299	case 16:
1300	case 24:
1301	case 30:
1302		break;
1303
1304	default:
1305		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1306			   "Given depth (%d) is not supported by %s driver\n",
1307			   pScrn->depth, AMDGPU_DRIVER_NAME);
1308		return FALSE;
1309	}
1310
1311	xf86PrintDepthBpp(pScrn);
1312
1313	info->pix24bpp = xf86GetBppFromDepth(pScrn, pScrn->depth);
1314	info->pixel_bytes = pScrn->bitsPerPixel / 8;
1315
1316	if (info->pix24bpp == 24) {
1317		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1318			   "Amdgpu does NOT support 24bpp\n");
1319		return FALSE;
1320	}
1321
1322	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1323		   "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n",
1324		   pScrn->depth,
1325		   info->pixel_bytes,
1326		   info->pixel_bytes > 1 ? "s" : "", info->pix24bpp);
1327
1328	if (!xf86SetDefaultVisual(pScrn, -1))
1329		return FALSE;
1330
1331	if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
1332		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1333			   "Default visual (%s) is not supported at depth %d\n",
1334			   xf86GetVisualName(pScrn->defaultVisual),
1335			   pScrn->depth);
1336		return FALSE;
1337	}
1338	return TRUE;
1339}
1340
1341/* This is called by AMDGPUPreInit to handle all color weight issues */
1342static Bool AMDGPUPreInitWeight(ScrnInfoPtr pScrn)
1343{
1344	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
1345
1346	/* Save flag for 6 bit DAC to use for
1347	   setting CRTC registers.  Otherwise use
1348	   an 8 bit DAC, even if xf86SetWeight sets
1349	   pScrn->rgbBits to some value other than
1350	   8. */
1351	info->dac6bits = FALSE;
1352
1353	if (pScrn->depth > 8) {
1354		rgb defaultWeight = { 0, 0, 0 };
1355
1356		if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight))
1357			return FALSE;
1358	} else {
1359		pScrn->rgbBits = 8;
1360	}
1361
1362	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1363		   "Using %d bits per RGB (%d bit DAC)\n",
1364		   pScrn->rgbBits, info->dac6bits ? 6 : 8);
1365
1366	return TRUE;
1367}
1368
1369static Bool AMDGPUPreInitAccel_KMS(ScrnInfoPtr pScrn)
1370{
1371	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
1372
1373	if (xf86ReturnOptValBool(info->Options, OPTION_ACCEL, TRUE)) {
1374		AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
1375		Bool use_glamor = TRUE;
1376#ifdef HAVE_GBM_BO_USE_LINEAR
1377		const char *accel_method;
1378
1379		accel_method = xf86GetOptValString(info->Options, OPTION_ACCEL_METHOD);
1380		if ((accel_method && !strcmp(accel_method, "none")))
1381			use_glamor = FALSE;
1382#endif
1383
1384#ifdef DRI2
1385		info->dri2.available = ! !xf86LoadSubModule(pScrn, "dri2");
1386#endif
1387
1388		if (info->dri2.available)
1389			info->gbm = gbm_create_device(pAMDGPUEnt->fd);
1390
1391		if (info->gbm) {
1392			if (use_glamor) {
1393				if (amdgpu_glamor_pre_init(pScrn))
1394					return TRUE;
1395
1396				xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1397					   "amdgpu_glamor_pre_init returned "
1398					   "FALSE, using ShadowFB\n");
1399			}
1400		} else {
1401			xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1402				   "gbm_create_device returned NULL, using "
1403				   "ShadowFB\n");
1404		}
1405	} else {
1406		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1407			   "GPU acceleration disabled, using ShadowFB\n");
1408	}
1409
1410	if (!xf86LoadSubModule(pScrn, "shadow"))
1411		return FALSE;
1412
1413	info->dri2.available = FALSE;
1414	info->shadow_fb = TRUE;
1415	return TRUE;
1416}
1417
1418static Bool AMDGPUPreInitChipType_KMS(ScrnInfoPtr pScrn,
1419				      struct amdgpu_gpu_info *gpu_info)
1420{
1421	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
1422	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
1423
1424	pScrn->chipset = (char*)amdgpu_get_marketing_name(pAMDGPUEnt->pDev);
1425	if (!pScrn->chipset)
1426		pScrn->chipset = "Unknown AMD Radeon GPU";
1427
1428	xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1429		   "Chipset: \"%s\" (ChipID = 0x%04x)\n",
1430		   pScrn->chipset, gpu_info->asic_id);
1431
1432	info->family = gpu_info->family_id;
1433
1434	return TRUE;
1435}
1436
1437static Bool amdgpu_get_tile_config(AMDGPUInfoPtr info,
1438				   struct amdgpu_gpu_info *gpu_info)
1439{
1440	switch ((gpu_info->gb_addr_cfg & 0x70) >> 4) {
1441	case 0:
1442		info->group_bytes = 256;
1443		break;
1444	case 1:
1445		info->group_bytes = 512;
1446		break;
1447	default:
1448		return FALSE;
1449	}
1450
1451	info->have_tiling_info = TRUE;
1452	return TRUE;
1453}
1454
1455static void AMDGPUSetupCapabilities(ScrnInfoPtr pScrn)
1456{
1457	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
1458	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
1459	uint64_t value;
1460	int ret;
1461
1462	pScrn->capabilities = 0;
1463
1464	/* PRIME offloading requires acceleration */
1465	if (!info->use_glamor)
1466		return;
1467
1468	ret = drmGetCap(pAMDGPUEnt->fd, DRM_CAP_PRIME, &value);
1469	if (ret == 0) {
1470		if (value & DRM_PRIME_CAP_EXPORT)
1471			pScrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SourceOffload;
1472		if (value & DRM_PRIME_CAP_IMPORT) {
1473			pScrn->capabilities |= RR_Capability_SinkOffload;
1474			if (info->drmmode.count_crtcs)
1475				pScrn->capabilities |= RR_Capability_SinkOutput;
1476		}
1477	}
1478}
1479
1480/* When the root window is created, initialize the screen contents from
1481 * console if -background none was specified on the command line
1482 */
1483static Bool AMDGPUCreateWindow_oneshot(WindowPtr pWin)
1484{
1485	ScreenPtr pScreen = pWin->drawable.pScreen;
1486	ScrnInfoPtr pScrn;
1487	AMDGPUInfoPtr info;
1488	Bool ret;
1489
1490	if (pWin != pScreen->root)
1491		ErrorF("%s called for non-root window %p\n", __func__, pWin);
1492
1493	pScrn = xf86ScreenToScrn(pScreen);
1494	info = AMDGPUPTR(pScrn);
1495	pScreen->CreateWindow = info->CreateWindow;
1496	ret = pScreen->CreateWindow(pWin);
1497
1498	if (ret)
1499		drmmode_copy_fb(pScrn, &info->drmmode);
1500
1501	return ret;
1502}
1503
1504static void amdgpu_determine_cursor_size(int fd, AMDGPUInfoPtr info)
1505{
1506	uint64_t value;
1507
1508	if (drmGetCap(fd, DRM_CAP_CURSOR_WIDTH, &value) == 0)
1509		info->cursor_w = value;
1510	else if (info->family < AMDGPU_FAMILY_CI)
1511		info->cursor_w = CURSOR_WIDTH;
1512	else
1513		info->cursor_w = CURSOR_WIDTH_CIK;
1514
1515	if (drmGetCap(fd, DRM_CAP_CURSOR_HEIGHT, &value) == 0)
1516		info->cursor_h = value;
1517	else if (info->family < AMDGPU_FAMILY_CI)
1518		info->cursor_h = CURSOR_HEIGHT;
1519	else
1520		info->cursor_h = CURSOR_HEIGHT_CIK;
1521}
1522
1523/* When the root window is mapped, set the initial modes */
1524void AMDGPUWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion
1525#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0)
1526				   , RegionPtr pBSRegion
1527#endif
1528				   )
1529{
1530	ScreenPtr pScreen = pWin->drawable.pScreen;
1531	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1532	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
1533
1534	if (pWin != pScreen->root)
1535		ErrorF("%s called for non-root window %p\n", __func__, pWin);
1536
1537	pScreen->WindowExposures = info->WindowExposures;
1538#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0)
1539	pScreen->WindowExposures(pWin, pRegion, pBSRegion);
1540#else
1541	pScreen->WindowExposures(pWin, pRegion);
1542#endif
1543
1544	amdgpu_glamor_finish(pScrn);
1545	drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE);
1546}
1547
1548Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
1549{
1550	AMDGPUInfoPtr info;
1551	AMDGPUEntPtr pAMDGPUEnt;
1552	struct amdgpu_gpu_info gpu_info;
1553	MessageType from;
1554	Gamma zeros = { 0.0, 0.0, 0.0 };
1555	int cpp;
1556	uint64_t heap_size = 0;
1557	uint64_t max_allocation = 0;
1558
1559	if (flags & PROBE_DETECT)
1560		return TRUE;
1561
1562	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
1563		       "AMDGPUPreInit_KMS\n");
1564	if (pScrn->numEntities != 1)
1565		return FALSE;
1566
1567	pAMDGPUEnt = xf86GetEntityPrivate(pScrn->entityList[0],
1568					  getAMDGPUEntityIndex())->ptr;
1569
1570	if (!AMDGPUGetRec(pScrn))
1571		return FALSE;
1572
1573	info = AMDGPUPTR(pScrn);
1574	info->instance_id = pAMDGPUEnt->num_scrns++;
1575	pAMDGPUEnt->scrn[info->instance_id] = pScrn;
1576
1577	info->pEnt =
1578	    xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
1579	if (info->pEnt->location.type != BUS_PCI
1580#ifdef XSERVER_PLATFORM_BUS
1581	    && info->pEnt->location.type != BUS_PLATFORM
1582#endif
1583	    )
1584		return FALSE;
1585
1586	if (xf86IsEntityShared(pScrn->entityList[0]) &&
1587	    info->instance_id == 0) {
1588		xf86SetPrimInitDone(pScrn->entityList[0]);
1589	}
1590
1591	pScrn->monitor = pScrn->confScreen->monitor;
1592
1593	if (!AMDGPUPreInitVisual(pScrn))
1594		return FALSE;
1595
1596	xf86CollectOptions(pScrn, NULL);
1597	if (!(info->Options = malloc(sizeof(AMDGPUOptions_KMS))))
1598		return FALSE;
1599
1600	memcpy(info->Options, AMDGPUOptions_KMS, sizeof(AMDGPUOptions_KMS));
1601	xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
1602
1603	if (!AMDGPUPreInitWeight(pScrn))
1604		return FALSE;
1605
1606	memset(&gpu_info, 0, sizeof(gpu_info));
1607	amdgpu_query_gpu_info(pAMDGPUEnt->pDev, &gpu_info);
1608
1609	if (!AMDGPUPreInitChipType_KMS(pScrn, &gpu_info))
1610		return FALSE;
1611
1612	info->dri2.available = FALSE;
1613	info->dri2.enabled = FALSE;
1614	info->dri2.pKernelDRMVersion = drmGetVersion(pAMDGPUEnt->fd);
1615	if (info->dri2.pKernelDRMVersion == NULL) {
1616		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1617			   "AMDGPUDRIGetVersion failed to get the DRM version\n");
1618		return FALSE;
1619	}
1620
1621	/* Get ScreenInit function */
1622	if (!xf86LoadSubModule(pScrn, "fb"))
1623		return FALSE;
1624
1625	if (!AMDGPUPreInitAccel_KMS(pScrn))
1626		return FALSE;
1627
1628	amdgpu_drm_queue_init(pScrn);
1629
1630	/* don't enable tiling if accel is not enabled */
1631	if (info->use_glamor) {
1632		/* set default group bytes, overridden by kernel info below */
1633		info->group_bytes = 256;
1634		info->have_tiling_info = FALSE;
1635		amdgpu_get_tile_config(info, &gpu_info);
1636	}
1637
1638	if (info->use_glamor) {
1639		from = X_DEFAULT;
1640
1641		info->tear_free = 2;
1642		if (xf86GetOptValBool(info->Options, OPTION_TEAR_FREE,
1643				      &info->tear_free))
1644			from = X_CONFIG;
1645		xf86DrvMsg(pScrn->scrnIndex, from, "TearFree property default: %s\n",
1646			   info->tear_free == 2 ? "auto" : (info->tear_free ? "on" : "off"));
1647
1648		info->shadow_primary =
1649			xf86ReturnOptValBool(info->Options, OPTION_SHADOW_PRIMARY, FALSE);
1650
1651		if (info->shadow_primary)
1652			xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowPrimary enabled\n");
1653
1654		if (!pScrn->is_gpu) {
1655			from = xf86GetOptValBool(info->Options, OPTION_VARIABLE_REFRESH,
1656						 &info->vrr_support) ? X_CONFIG : X_DEFAULT;
1657
1658			xf86DrvMsg(pScrn->scrnIndex, from, "VariableRefresh: %sabled\n",
1659				   info->vrr_support ? "en" : "dis");
1660
1661			info->async_flip_secondaries = FALSE;
1662			from = xf86GetOptValBool(info->Options, OPTION_ASYNC_FLIP_SECONDARIES,
1663						 &info->async_flip_secondaries) ? X_CONFIG : X_DEFAULT;
1664
1665			xf86DrvMsg(pScrn->scrnIndex, from, "AsyncFlipSecondaries: %sabled\n",
1666				   info->async_flip_secondaries ? "en" : "dis");
1667		}
1668	}
1669
1670	if (!pScrn->is_gpu) {
1671		info->allowPageFlip = xf86ReturnOptValBool(info->Options,
1672							   OPTION_PAGE_FLIP,
1673							   TRUE);
1674		if (info->shadow_primary) {
1675			xf86DrvMsg(pScrn->scrnIndex,
1676				   info->allowPageFlip ? X_WARNING : X_DEFAULT,
1677				   "KMS Pageflipping: disabled%s\n",
1678				   info->allowPageFlip ?
1679				   " because of ShadowPrimary" : "");
1680			info->allowPageFlip = FALSE;
1681		} else {
1682			xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1683				   "KMS Pageflipping: %sabled\n",
1684				   info->allowPageFlip ? "en" : "dis");
1685		}
1686	}
1687
1688	if (xf86ReturnOptValBool(info->Options, OPTION_DELETE_DP12, FALSE)) {
1689		info->drmmode.delete_dp_12_displays = TRUE;
1690	}
1691
1692	if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) ==
1693	    FALSE) {
1694		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1695			   "Kernel modesetting setup failed\n");
1696		return FALSE;
1697	}
1698
1699	AMDGPUSetupCapabilities(pScrn);
1700
1701	if (info->drmmode.count_crtcs == 1)
1702		pAMDGPUEnt->HasCRTC2 = FALSE;
1703	else
1704		pAMDGPUEnt->HasCRTC2 = TRUE;
1705
1706	amdgpu_determine_cursor_size(pAMDGPUEnt->fd, info);
1707
1708	amdgpu_query_heap_size(pAMDGPUEnt->pDev, AMDGPU_GEM_DOMAIN_GTT,
1709				&heap_size, &max_allocation);
1710	info->gart_size = heap_size;
1711	amdgpu_query_heap_size(pAMDGPUEnt->pDev, AMDGPU_GEM_DOMAIN_VRAM,
1712				&heap_size, &max_allocation);
1713	info->vram_size = max_allocation;
1714
1715	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1716		   "mem size init: gart size :%llx vram size: s:%llx visible:%llx\n",
1717		   (unsigned long long)info->gart_size,
1718		   (unsigned long long)heap_size,
1719		   (unsigned long long)max_allocation);
1720
1721	cpp = pScrn->bitsPerPixel / 8;
1722	pScrn->displayWidth =
1723	    AMDGPU_ALIGN(pScrn->virtualX, drmmode_get_pitch_align(pScrn, cpp));
1724
1725	/* Set display resolution */
1726	xf86SetDpi(pScrn, 0, 0);
1727
1728	if (!xf86SetGamma(pScrn, zeros))
1729		return FALSE;
1730
1731	if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
1732		if (!xf86LoadSubModule(pScrn, "ramdac"))
1733			return FALSE;
1734	}
1735
1736	if (!pScrn->modes
1737#ifdef XSERVER_PLATFORM_BUS
1738	    && !pScrn->is_gpu
1739#endif
1740	    ) {
1741		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
1742		return FALSE;
1743	}
1744
1745	return TRUE;
1746}
1747
1748static Bool AMDGPUCursorInit_KMS(ScreenPtr pScreen)
1749{
1750	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1751	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
1752
1753	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
1754		       "Initializing Cursor\n");
1755
1756	/* Set Silken Mouse */
1757	xf86SetSilkenMouse(pScreen);
1758
1759	/* Cursor setup */
1760	miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
1761
1762	if (info->allowPageFlip) {
1763		miPointerScreenPtr PointPriv =
1764			dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
1765
1766		if (!dixRegisterScreenPrivateKey(&amdgpu_device_private_key, pScreen,
1767						 PRIVATE_DEVICE,
1768						 sizeof(struct amdgpu_device_priv))) {
1769			xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "dixRegisterScreenPrivateKey failed\n");
1770			return FALSE;
1771		}
1772
1773		info->SpriteFuncs = PointPriv->spriteFuncs;
1774		PointPriv->spriteFuncs = &drmmode_sprite_funcs;
1775	}
1776
1777	if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE))
1778		return TRUE;
1779
1780	if (!xf86_cursors_init(pScreen, info->cursor_w, info->cursor_h,
1781			       HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
1782			       HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
1783			       HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
1784			       HARDWARE_CURSOR_UPDATE_UNHIDDEN |
1785			       HARDWARE_CURSOR_ARGB)) {
1786		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86_cursors_init failed\n");
1787		return FALSE;
1788	}
1789
1790	return TRUE;
1791}
1792
1793void AMDGPUBlank(ScrnInfoPtr pScrn)
1794{
1795	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1796	xf86OutputPtr output;
1797	xf86CrtcPtr crtc;
1798	int o, c;
1799
1800	for (c = 0; c < xf86_config->num_crtc; c++) {
1801		crtc = xf86_config->crtc[c];
1802		for (o = 0; o < xf86_config->num_output; o++) {
1803			output = xf86_config->output[o];
1804			if (output->crtc != crtc)
1805				continue;
1806
1807			output->funcs->dpms(output, DPMSModeOff);
1808		}
1809		crtc->funcs->dpms(crtc, DPMSModeOff);
1810	}
1811}
1812
1813void AMDGPUUnblank(ScrnInfoPtr pScrn)
1814{
1815	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1816	xf86OutputPtr output;
1817	xf86CrtcPtr crtc;
1818	int o, c;
1819	for (c = 0; c < xf86_config->num_crtc; c++) {
1820		crtc = xf86_config->crtc[c];
1821		if (!crtc->enabled)
1822			continue;
1823		crtc->funcs->dpms(crtc, DPMSModeOn);
1824		for (o = 0; o < xf86_config->num_output; o++) {
1825			output = xf86_config->output[o];
1826			if (output->crtc != crtc)
1827				continue;
1828			output->funcs->dpms(output, DPMSModeOn);
1829		}
1830	}
1831}
1832
1833static Bool amdgpu_set_drm_master(ScrnInfoPtr pScrn)
1834{
1835	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
1836	int err;
1837
1838#ifdef XF86_PDEV_SERVER_FD
1839	if (pAMDGPUEnt->platform_dev &&
1840	    (pAMDGPUEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
1841		return TRUE;
1842#endif
1843
1844	err = drmSetMaster(pAMDGPUEnt->fd);
1845	if (err)
1846		ErrorF("Unable to retrieve master\n");
1847
1848	return err == 0;
1849}
1850
1851static void amdgpu_drop_drm_master(ScrnInfoPtr pScrn)
1852{
1853	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
1854
1855#ifdef XF86_PDEV_SERVER_FD
1856	if (pAMDGPUEnt->platform_dev &&
1857	    (pAMDGPUEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
1858		return;
1859#endif
1860
1861	drmDropMaster(pAMDGPUEnt->fd);
1862}
1863
1864
1865static
1866CARD32 cleanup_black_fb(OsTimerPtr timer, CARD32 now, pointer data)
1867{
1868	ScreenPtr screen = data;
1869	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
1870	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
1871	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
1872	int c;
1873
1874	if (xf86ScreenToScrn(amdgpu_primary_screen(screen))->vtSema)
1875		return 0;
1876
1877	/* Unreference the all-black FB created by AMDGPULeaveVT_KMS. After
1878	 * this, there should be no FB left created by this driver.
1879	 */
1880	for (c = 0; c < xf86_config->num_crtc; c++) {
1881		drmmode_crtc_private_ptr drmmode_crtc =
1882			xf86_config->crtc[c]->driver_private;
1883
1884		drmmode_fb_reference(pAMDGPUEnt->fd, &drmmode_crtc->fb, NULL);
1885	}
1886
1887	TimerFree(timer);
1888	return 0;
1889}
1890
1891static Bool AMDGPUSaveScreen_KMS(ScreenPtr pScreen, int mode)
1892{
1893	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1894	Bool unblank;
1895
1896	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
1897		       "AMDGPUSaveScreen(%d)\n", mode);
1898
1899	unblank = xf86IsUnblank(mode);
1900	if (unblank)
1901		SetTimeSinceLastInputEvent();
1902
1903	if ((pScrn != NULL) && pScrn->vtSema) {
1904		if (unblank)
1905			AMDGPUUnblank(pScrn);
1906		else
1907			AMDGPUBlank(pScrn);
1908	}
1909	return TRUE;
1910}
1911
1912/* Called at the end of each server generation.  Restore the original
1913 * text mode, unmap video memory, and unwrap and call the saved
1914 * CloseScreen function.
1915 */
1916static Bool AMDGPUCloseScreen_KMS(ScreenPtr pScreen)
1917{
1918	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1919	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
1920	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
1921
1922	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
1923		       "AMDGPUCloseScreen\n");
1924
1925	/* Clear mask of assigned crtc's in this generation */
1926	pAMDGPUEnt->assigned_crtcs = 0;
1927
1928	drmmode_uevent_fini(pScrn, &info->drmmode);
1929	amdgpu_drm_queue_close(pScrn);
1930
1931	if (info->callback_event_type != -1) {
1932		DeleteCallback(&EventCallback, amdgpu_event_callback, pScrn);
1933		DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn);
1934	}
1935
1936	amdgpu_sync_close(pScreen);
1937	amdgpu_drop_drm_master(pScrn);
1938
1939	drmmode_fini(pScrn, &info->drmmode);
1940	if (info->dri2.enabled) {
1941		amdgpu_dri2_close_screen(pScreen);
1942	}
1943	amdgpu_glamor_fini(pScreen);
1944	pScrn->vtSema = FALSE;
1945	xf86ClearPrimInitDone(info->pEnt->index);
1946
1947	if (info->allowPageFlip) {
1948		miPointerScreenPtr PointPriv =
1949			dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
1950
1951		if (PointPriv->spriteFuncs == &drmmode_sprite_funcs)
1952			PointPriv->spriteFuncs = info->SpriteFuncs;
1953	}
1954
1955	pScreen->BlockHandler = info->BlockHandler;
1956	pScreen->CloseScreen = info->CloseScreen;
1957	return pScreen->CloseScreen(pScreen);
1958}
1959
1960void AMDGPUFreeScreen_KMS(ScrnInfoPtr pScrn)
1961{
1962	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
1963		       "AMDGPUFreeScreen\n");
1964
1965	AMDGPUFreeRec(pScrn);
1966}
1967
1968Bool AMDGPUScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv)
1969{
1970	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1971	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
1972	int subPixelOrder = SubPixelUnknown;
1973	MessageType from;
1974	Bool value;
1975	int driLevel;
1976	const char *s;
1977	void *front_ptr;
1978
1979	pScrn->fbOffset = 0;
1980
1981	miClearVisualTypes();
1982	if (!miSetVisualTypes(pScrn->depth,
1983			      miGetDefaultVisualMask(pScrn->depth),
1984			      pScrn->rgbBits, pScrn->defaultVisual))
1985		return FALSE;
1986	miSetPixmapDepths();
1987
1988	if (!amdgpu_set_drm_master(pScrn))
1989		return FALSE;
1990
1991	info->directRenderingEnabled = FALSE;
1992	if (info->shadow_fb == FALSE)
1993		info->directRenderingEnabled = amdgpu_dri2_screen_init(pScreen);
1994
1995	if (!amdgpu_setup_kernel_mem(pScreen)) {
1996		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1997			   "amdgpu_setup_kernel_mem failed\n");
1998		return FALSE;
1999	}
2000	front_ptr = info->front_buffer->cpu_ptr;
2001
2002	if (info->shadow_fb) {
2003		info->fb_shadow = calloc(1,
2004					 pScrn->displayWidth * pScrn->virtualY *
2005					 ((pScrn->bitsPerPixel + 7) >> 3));
2006		if (!info->fb_shadow) {
2007			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2008				   "Failed to allocate shadow framebuffer\n");
2009			return FALSE;
2010		} else {
2011			if (!fbScreenInit(pScreen, info->fb_shadow,
2012					  pScrn->virtualX, pScrn->virtualY,
2013					  pScrn->xDpi, pScrn->yDpi,
2014					  pScrn->displayWidth,
2015					  pScrn->bitsPerPixel))
2016				return FALSE;
2017		}
2018	}
2019
2020	if (info->shadow_fb == FALSE) {
2021		/* Init fb layer */
2022		if (!fbScreenInit(pScreen, front_ptr,
2023				  pScrn->virtualX, pScrn->virtualY,
2024				  pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
2025				  pScrn->bitsPerPixel))
2026			return FALSE;
2027	}
2028
2029	xf86SetBlackWhitePixels(pScreen);
2030
2031	if (pScrn->bitsPerPixel > 8) {
2032		VisualPtr visual;
2033
2034		visual = pScreen->visuals + pScreen->numVisuals;
2035		while (--visual >= pScreen->visuals) {
2036			if ((visual->class | DynamicClass) == DirectColor) {
2037				visual->offsetRed = pScrn->offset.red;
2038				visual->offsetGreen = pScrn->offset.green;
2039				visual->offsetBlue = pScrn->offset.blue;
2040				visual->redMask = pScrn->mask.red;
2041				visual->greenMask = pScrn->mask.green;
2042				visual->blueMask = pScrn->mask.blue;
2043			}
2044		}
2045	}
2046
2047	/* Must be after RGB order fixed */
2048	fbPictureInit(pScreen, 0, 0);
2049
2050#ifdef RENDER
2051	if ((s = xf86GetOptValString(info->Options, OPTION_SUBPIXEL_ORDER))) {
2052		if (strcmp(s, "RGB") == 0)
2053			subPixelOrder = SubPixelHorizontalRGB;
2054		else if (strcmp(s, "BGR") == 0)
2055			subPixelOrder = SubPixelHorizontalBGR;
2056		else if (strcmp(s, "NONE") == 0)
2057			subPixelOrder = SubPixelNone;
2058		PictureSetSubpixelOrder(pScreen, subPixelOrder);
2059	}
2060#endif
2061
2062	if (xorgGetVersion() >= XORG_VERSION_NUMERIC(1,18,3,0,0))
2063		value = info->use_glamor;
2064	else
2065		value = FALSE;
2066	from = X_DEFAULT;
2067
2068	if (info->use_glamor) {
2069		if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value))
2070			from = X_CONFIG;
2071
2072		if (xf86GetOptValInteger(info->Options, OPTION_DRI, &driLevel) &&
2073				(driLevel == 2 || driLevel == 3)) {
2074			from = X_CONFIG;
2075			value = driLevel == 3;
2076		}
2077	}
2078
2079	if (value) {
2080		value = amdgpu_sync_init(pScreen) &&
2081			amdgpu_present_screen_init(pScreen) &&
2082			amdgpu_dri3_screen_init(pScreen);
2083
2084		if (!value)
2085			from = X_WARNING;
2086	}
2087
2088	xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %sabled\n", value ? "en" : "dis");
2089
2090	pScrn->vtSema = TRUE;
2091	xf86SetBackingStore(pScreen);
2092
2093	if (info->directRenderingEnabled) {
2094		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2095			   "Direct rendering enabled\n");
2096	} else {
2097		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2098			   "Direct rendering disabled\n");
2099	}
2100
2101	if (info->use_glamor && info->directRenderingEnabled) {
2102		xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
2103			       "Initializing Acceleration\n");
2104		if (amdgpu_glamor_init(pScreen)) {
2105			xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2106				   "Acceleration enabled\n");
2107		} else {
2108			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2109				   "Acceleration initialization failed\n");
2110			xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2111				   "2D and 3D acceleration disabled\n");
2112			info->use_glamor = FALSE;
2113		}
2114	} else if (info->directRenderingEnabled) {
2115		if (!amdgpu_pixmap_init(pScreen))
2116			xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D acceleration disabled\n");
2117		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D acceleration disabled\n");
2118	} else {
2119		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D and 3D acceleration disabled\n");
2120	}
2121
2122	/* Init DPMS */
2123	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
2124		       "Initializing DPMS\n");
2125	xf86DPMSInit(pScreen, xf86DPMSSet, 0);
2126
2127	if (!AMDGPUCursorInit_KMS(pScreen))
2128		return FALSE;
2129
2130	/* DGA setup */
2131#ifdef XFreeXDGA
2132	/* DGA is dangerous on kms as the base and framebuffer location may change:
2133	 * http://lists.freedesktop.org/archives/xorg-devel/2009-September/002113.html
2134	 */
2135	/* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */
2136#endif
2137	if (info->shadow_fb == FALSE && !pScreen->isGPU) {
2138		/* Init Xv */
2139		xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
2140			       "Initializing Xv\n");
2141		AMDGPUInitVideo(pScreen);
2142	}
2143
2144	if (info->shadow_fb == TRUE) {
2145		if (!shadowSetup(pScreen)) {
2146			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2147				   "Shadowfb initialization failed\n");
2148			return FALSE;
2149		}
2150	}
2151	pScrn->pScreen = pScreen;
2152
2153	if (!pScreen->isGPU) {
2154		if (serverGeneration == 1 && bgNoneRoot && info->use_glamor) {
2155			info->CreateWindow = pScreen->CreateWindow;
2156			pScreen->CreateWindow = AMDGPUCreateWindow_oneshot;
2157		}
2158		info->WindowExposures = pScreen->WindowExposures;
2159		pScreen->WindowExposures = AMDGPUWindowExposures_oneshot;
2160	}
2161
2162	/* Provide SaveScreen & wrap BlockHandler and CloseScreen */
2163	/* Wrap CloseScreen */
2164	info->CloseScreen = pScreen->CloseScreen;
2165	pScreen->CloseScreen = AMDGPUCloseScreen_KMS;
2166	pScreen->SaveScreen = AMDGPUSaveScreen_KMS;
2167	info->BlockHandler = pScreen->BlockHandler;
2168	pScreen->BlockHandler = AMDGPUBlockHandler_KMS;
2169
2170	info->CreateScreenResources = pScreen->CreateScreenResources;
2171	pScreen->CreateScreenResources = AMDGPUCreateScreenResources_KMS;
2172
2173	pScreen->StartPixmapTracking = PixmapStartDirtyTracking;
2174	pScreen->StopPixmapTracking = PixmapStopDirtyTracking;
2175#if HAS_SYNC_SHARED_PIXMAP
2176	pScreen->SyncSharedPixmap = amdgpu_sync_shared_pixmap;
2177#endif
2178
2179	if (!xf86CrtcScreenInit(pScreen))
2180		return FALSE;
2181
2182	/* Wrap pointer motion to flip touch screen around */
2183//    info->PointerMoved = pScrn->PointerMoved;
2184//    pScrn->PointerMoved = AMDGPUPointerMoved;
2185
2186	if (!drmmode_setup_colormap(pScreen, pScrn))
2187		return FALSE;
2188
2189	/* Note unused options */
2190	if (serverGeneration == 1)
2191		xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
2192
2193	if (info->vrr_support) {
2194		if (!amdgpu_property_vectors_wrapped) {
2195			saved_change_property = ProcVector[X_ChangeProperty];
2196			ProcVector[X_ChangeProperty] = amdgpu_change_property;
2197			saved_delete_property = ProcVector[X_DeleteProperty];
2198			ProcVector[X_DeleteProperty] = amdgpu_delete_property;
2199			amdgpu_property_vectors_wrapped = TRUE;
2200		}
2201
2202		amdgpu_vrr_atom = MakeAtom("_VARIABLE_REFRESH",
2203					   strlen("_VARIABLE_REFRESH"), TRUE);
2204	}
2205
2206	drmmode_init(pScrn, &info->drmmode);
2207
2208	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
2209		       "AMDGPUScreenInit finished\n");
2210
2211	return TRUE;
2212}
2213
2214Bool AMDGPUEnterVT_KMS(ScrnInfoPtr pScrn)
2215{
2216	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
2217
2218	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
2219		       "AMDGPUEnterVT_KMS\n");
2220
2221	amdgpu_set_drm_master(pScrn);
2222
2223	if (info->shadow_fb) {
2224		int pitch;
2225		struct amdgpu_buffer *front_buffer =
2226			amdgpu_alloc_pixmap_bo(pScrn, pScrn->virtualX,
2227					       pScrn->virtualY, pScrn->depth,
2228					       AMDGPU_CREATE_PIXMAP_SCANOUT |
2229					       AMDGPU_CREATE_PIXMAP_LINEAR,
2230					       pScrn->bitsPerPixel,
2231					       &pitch);
2232
2233		if (front_buffer) {
2234			if (amdgpu_bo_map(pScrn, front_buffer) == 0) {
2235				memset(front_buffer->cpu_ptr, 0, pitch * pScrn->virtualY);
2236				amdgpu_bo_unref(&info->front_buffer);
2237				info->front_buffer = front_buffer;
2238			} else {
2239				amdgpu_bo_unref(&front_buffer);
2240				front_buffer = NULL;
2241			}
2242		}
2243
2244		if (!front_buffer) {
2245			xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2246				   "Failed to allocate new scanout BO after VT switch, "
2247				   "other DRM masters may see screen contents\n");
2248		}
2249	}
2250
2251	pScrn->vtSema = TRUE;
2252
2253	if (!drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE))
2254		return FALSE;
2255
2256	return TRUE;
2257}
2258
2259static void
2260pixmap_unref_fb(PixmapPtr pixmap)
2261{
2262	ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
2263	struct drmmode_fb **fb_ptr = amdgpu_pixmap_get_fb_ptr(pixmap);
2264	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
2265
2266	if (fb_ptr)
2267		drmmode_fb_reference(pAMDGPUEnt->fd, fb_ptr, NULL);
2268}
2269
2270static void
2271client_pixmap_unref_fb(void *value, XID id, void *pScreen)
2272{
2273	PixmapPtr pixmap = value;
2274
2275	if (pixmap->drawable.pScreen == pScreen)
2276		pixmap_unref_fb(pixmap);
2277}
2278
2279void AMDGPULeaveVT_KMS(ScrnInfoPtr pScrn)
2280{
2281	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
2282	ScreenPtr pScreen = pScrn->pScreen;
2283
2284	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
2285		       "AMDGPULeaveVT_KMS\n");
2286
2287	if (!info->shadow_fb) {
2288		AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
2289		xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2290		xf86CrtcPtr crtc;
2291		drmmode_crtc_private_ptr drmmode_crtc;
2292		unsigned w = 0, h = 0;
2293		int i;
2294
2295		/* If we're called from CloseScreen, trying to clear the black
2296		 * scanout BO will likely crash and burn
2297		 */
2298		if (!pScreen->GCperDepth[0])
2299			goto hide_cursors;
2300
2301		/* Compute maximum scanout dimensions of active CRTCs */
2302		for (i = 0; i < xf86_config->num_crtc; i++) {
2303			crtc = xf86_config->crtc[i];
2304			drmmode_crtc = crtc->driver_private;
2305
2306			if (!drmmode_crtc->fb)
2307				continue;
2308
2309			w = max(w, crtc->mode.HDisplay);
2310			h = max(h, crtc->mode.VDisplay);
2311		}
2312
2313		/* Make all active CRTCs scan out from an all-black framebuffer */
2314		if (w > 0 && h > 0) {
2315			PixmapPtr black_scanout =
2316				pScreen->CreatePixmap(pScreen, w, h, pScrn->depth,
2317						      AMDGPU_CREATE_PIXMAP_SCANOUT);
2318
2319			if (black_scanout) {
2320				struct drmmode_fb *black_fb =
2321					amdgpu_pixmap_get_fb(black_scanout);
2322
2323				amdgpu_pixmap_clear(black_scanout);
2324				amdgpu_glamor_finish(pScrn);
2325
2326				for (i = 0; i < xf86_config->num_crtc; i++) {
2327					crtc = xf86_config->crtc[i];
2328					drmmode_crtc = crtc->driver_private;
2329
2330					if (drmmode_crtc->fb) {
2331						if (black_fb) {
2332							drmmode_set_mode(crtc, black_fb, &crtc->mode, 0, 0);
2333						} else {
2334							drmModeSetCrtc(pAMDGPUEnt->fd,
2335								       drmmode_crtc->mode_crtc->crtc_id, 0,
2336								       0, 0, NULL, 0, NULL);
2337							drmmode_fb_reference(pAMDGPUEnt->fd,
2338									     &drmmode_crtc->fb, NULL);
2339						}
2340
2341						if (pScrn->is_gpu) {
2342							if (drmmode_crtc->scanout[0])
2343								pixmap_unref_fb(drmmode_crtc->scanout[0]);
2344							if (drmmode_crtc->scanout[1])
2345								pixmap_unref_fb(drmmode_crtc->scanout[1]);
2346						} else {
2347							drmmode_crtc_scanout_free(crtc);
2348						}
2349					}
2350				}
2351
2352				pScreen->DestroyPixmap(black_scanout);
2353			}
2354		}
2355
2356		xf86RotateFreeShadow(pScrn);
2357
2358		/* Unreference FBs of all pixmaps. After this, the only FB remaining
2359		 * should be the all-black one being scanned out by active CRTCs
2360		 */
2361		for (i = 0; i < currentMaxClients; i++) {
2362			if (i > 0 &&
2363			    (!clients[i] || clients[i]->clientState != ClientStateRunning))
2364				continue;
2365
2366			FindClientResourcesByType(clients[i], RT_PIXMAP,
2367						  client_pixmap_unref_fb, pScreen);
2368		}
2369
2370		pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen));
2371	} else {
2372		memset(info->front_buffer->cpu_ptr, 0, pScrn->virtualX *
2373		       info->pixel_bytes * pScrn->virtualY);
2374	}
2375
2376	if (pScreen->GCperDepth[0])
2377		TimerSet(NULL, 0, 1000, cleanup_black_fb, pScreen);
2378
2379 hide_cursors:
2380	xf86_hide_cursors(pScrn);
2381
2382	amdgpu_drop_drm_master(pScrn);
2383
2384	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
2385		       "Ok, leaving now...\n");
2386}
2387
2388Bool AMDGPUSwitchMode_KMS(ScrnInfoPtr pScrn, DisplayModePtr mode)
2389{
2390	Bool ret;
2391	ret = xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
2392	return ret;
2393
2394}
2395
2396void AMDGPUAdjustFrame_KMS(ScrnInfoPtr pScrn, int x, int y)
2397{
2398	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
2399	drmmode_adjust_frame(pScrn, &info->drmmode, x, y);
2400	return;
2401}
2402
2403static Bool amdgpu_setup_kernel_mem(ScreenPtr pScreen)
2404{
2405	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
2406	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
2407	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
2408	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2409	int cpp = info->pixel_bytes;
2410	int cursor_size;
2411	int c, i;
2412
2413	cursor_size = info->cursor_w * info->cursor_h * 4;
2414	cursor_size = AMDGPU_ALIGN(cursor_size, AMDGPU_GPU_PAGE_SIZE);
2415	for (c = 0; c < xf86_config->num_crtc; c++) {
2416		drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[c]->driver_private;
2417
2418		for (i = 0; i < 2; i++) {
2419			if (!drmmode_crtc->cursor_buffer[i]) {
2420				drmmode_crtc->cursor_buffer[i] =
2421					amdgpu_bo_open(pAMDGPUEnt->pDev,
2422						       cursor_size, 0,
2423						       AMDGPU_GEM_DOMAIN_VRAM);
2424
2425				if (!(drmmode_crtc->cursor_buffer[i])) {
2426					ErrorF("Failed to allocate cursor buffer memory\n");
2427					return FALSE;
2428				}
2429
2430				if (amdgpu_bo_cpu_map(drmmode_crtc->cursor_buffer[i]->bo.amdgpu,
2431						      &drmmode_crtc->cursor_buffer[i]->cpu_ptr))
2432					ErrorF("Failed to map cursor buffer memory\n");
2433			}
2434		}
2435	}
2436
2437	if (!info->front_buffer) {
2438		int pitch;
2439		int hint = AMDGPU_CREATE_PIXMAP_SCANOUT;
2440
2441		if (info->shadow_primary)
2442			hint |= AMDGPU_CREATE_PIXMAP_LINEAR | AMDGPU_CREATE_PIXMAP_GTT;
2443		else if (!info->use_glamor)
2444			hint |= AMDGPU_CREATE_PIXMAP_LINEAR;
2445
2446		info->front_buffer =
2447			amdgpu_alloc_pixmap_bo(pScrn, pScrn->virtualX,
2448					       pScrn->virtualY, pScrn->depth,
2449					       hint, pScrn->bitsPerPixel,
2450					       &pitch);
2451		if (!(info->front_buffer)) {
2452			ErrorF("Failed to allocate front buffer memory\n");
2453			return FALSE;
2454		}
2455
2456		if (!info->use_glamor &&
2457		    amdgpu_bo_map(pScrn, info->front_buffer) != 0) {
2458			ErrorF("Failed to map front buffer memory\n");
2459			return FALSE;
2460		}
2461
2462		pScrn->displayWidth = pitch / cpp;
2463	}
2464
2465	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer pitch: %d bytes\n",
2466		   pScrn->displayWidth * cpp);
2467	return TRUE;
2468}
2469
2470/* Used to disallow modes that are not supported by the hardware */
2471ModeStatus AMDGPUValidMode(ScrnInfoPtr pScrn, DisplayModePtr mode,
2472			   Bool verbose, int flag)
2473{
2474	/* There are problems with double scan mode at high clocks
2475	 * They're likely related PLL and display buffer settings.
2476	 * Disable these modes for now.
2477	 */
2478	if (mode->Flags & V_DBLSCAN) {
2479		if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
2480			return MODE_CLOCK_RANGE;
2481	}
2482	return MODE_OK;
2483}
2484