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