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