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