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