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