1/*
2 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
3 *                VA Linux Systems Inc., Fremont, California.
4 *
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation on the rights to use, copy, modify, merge,
11 * publish, distribute, sublicense, and/or sell copies of the Software,
12 * and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial
17 * portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
23 * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 */
28
29/*
30 * Authors:
31 *   Kevin E. Martin <martin@xfree86.org>
32 *   Rickard E. Faith <faith@valinux.com>
33 *   Alan Hourihane <alanh@fairlite.demon.co.uk>
34 *
35 */
36
37#ifndef _AMDGPU_DRV_H_
38#define _AMDGPU_DRV_H_
39
40#include <stdlib.h>		/* For abs() */
41#include <unistd.h>		/* For usleep() */
42#include <sys/time.h>		/* For gettimeofday() */
43
44#include "config.h"
45
46#include "xf86str.h"
47#include "compiler.h"
48
49/* PCI support */
50#include "xf86Pci.h"
51
52#include "fb.h"
53
54/* Cursor Support */
55#include "xf86Cursor.h"
56
57/* DDC support */
58#include "xf86DDC.h"
59
60/* Xv support */
61#include "xf86xv.h"
62
63#include "amdgpu_probe.h"
64
65/* DRI support */
66#include "xf86drm.h"
67#include "amdgpu_drm.h"
68
69#ifdef DAMAGE
70#include "damage.h"
71#include "globals.h"
72#endif
73
74#include "xf86Crtc.h"
75#include "X11/Xatom.h"
76
77#include "amdgpu_dri2.h"
78#include "drmmode_display.h"
79#include "amdgpu_bo_helper.h"
80
81/* Render support */
82#ifdef RENDER
83#include "picturestr.h"
84#endif
85
86#include "compat-api.h"
87
88#include "simple_list.h"
89
90struct _SyncFence;
91
92#ifndef HAVE_REGIONDUPLICATE
93
94static inline RegionPtr
95RegionDuplicate(RegionPtr pOld)
96{
97	RegionPtr pNew;
98
99	pNew = RegionCreate(&pOld->extents, 0);
100	if (!pNew)
101		return NULL;
102	if (!RegionCopy(pNew, pOld)) {
103		RegionDestroy(pNew);
104		return NULL;
105	}
106	return pNew;
107}
108
109#endif
110
111#ifndef MAX
112#define MAX(a,b) ((a)>(b)?(a):(b))
113#endif
114#ifndef MIN
115#define MIN(a,b) ((a)>(b)?(b):(a))
116#endif
117
118#if HAVE_BYTESWAP_H
119#include <byteswap.h>
120#elif defined(USE_SYS_ENDIAN_H)
121#include <sys/endian.h>
122#else
123#define bswap_16(value)  \
124        ((((value) & 0xff) << 8) | ((value) >> 8))
125
126#define bswap_32(value) \
127        (((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \
128        (uint32_t)bswap_16((uint16_t)((value) >> 16)))
129
130#define bswap_64(value) \
131        (((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) \
132            << 32) | \
133        (uint64_t)bswap_32((uint32_t)((value) >> 32)))
134#endif
135
136#if X_BYTE_ORDER == X_BIG_ENDIAN
137#define le32_to_cpu(x) bswap_32(x)
138#define le16_to_cpu(x) bswap_16(x)
139#define cpu_to_le32(x) bswap_32(x)
140#define cpu_to_le16(x) bswap_16(x)
141#else
142#define le32_to_cpu(x) (x)
143#define le16_to_cpu(x) (x)
144#define cpu_to_le32(x) (x)
145#define cpu_to_le16(x) (x)
146#endif
147
148/* Provide substitutes for gcc's __FUNCTION__ on other compilers */
149#if !defined(__GNUC__) && !defined(__FUNCTION__)
150#define __FUNCTION__ __func__	/* C99 */
151#endif
152
153typedef enum {
154	OPTION_ACCEL,
155	OPTION_SW_CURSOR,
156	OPTION_PAGE_FLIP,
157#ifdef RENDER
158	OPTION_SUBPIXEL_ORDER,
159#endif
160	OPTION_ZAPHOD_HEADS,
161	OPTION_ACCEL_METHOD,
162	OPTION_DRI3,
163	OPTION_DRI,
164	OPTION_SHADOW_PRIMARY,
165	OPTION_TEAR_FREE,
166	OPTION_DELETE_DP12,
167	OPTION_VARIABLE_REFRESH,
168	OPTION_ASYNC_FLIP_SECONDARIES,
169} AMDGPUOpts;
170
171static inline ScreenPtr
172amdgpu_primary_screen(ScreenPtr screen)
173{
174	if (screen->current_primary)
175		return screen->current_primary;
176
177	return screen;
178}
179
180static inline ScreenPtr
181amdgpu_dirty_primary(PixmapDirtyUpdatePtr dirty)
182{
183	return amdgpu_primary_screen(dirty->secondary_dst->drawable.pScreen);
184}
185
186static inline DrawablePtr
187amdgpu_dirty_src_drawable(PixmapDirtyUpdatePtr dirty)
188{
189#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC
190	return dirty->src;
191#else
192	return &dirty->src->drawable;
193#endif
194}
195
196static inline Bool
197amdgpu_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap)
198{
199	return amdgpu_dirty_src_drawable(dirty) == &pixmap->drawable;
200}
201
202
203#define AMDGPU_VSYNC_TIMEOUT	20000	/* Maximum wait for VSYNC (in usecs) */
204
205/* Buffer are aligned on 4096 byte boundaries */
206#define AMDGPU_GPU_PAGE_SIZE 4096
207#define AMDGPU_BUFFER_ALIGN (AMDGPU_GPU_PAGE_SIZE - 1)
208
209#define xFixedToFloat(f) (((float) (f)) / 65536)
210
211#define AMDGPU_LOGLEVEL_DEBUG 4
212
213/* Other macros */
214#define AMDGPU_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
215#define AMDGPUPTR(pScrn)      ((AMDGPUInfoPtr)(pScrn)->driverPrivate)
216
217#define CURSOR_WIDTH	64
218#define CURSOR_HEIGHT	64
219
220#define CURSOR_WIDTH_CIK	128
221#define CURSOR_HEIGHT_CIK	128
222
223#define AMDGPU_BO_FLAGS_GBM	0x1
224
225struct amdgpu_buffer {
226	union {
227		struct gbm_bo *gbm;
228		amdgpu_bo_handle amdgpu;
229	} bo;
230	void *cpu_ptr;
231	uint32_t ref_count;
232	uint32_t flags;
233};
234
235struct amdgpu_client_priv {
236	uint_fast32_t needs_flush;
237};
238
239struct amdgpu_device_priv {
240	CursorPtr cursor;
241	Bool sprite_visible;
242};
243
244struct amdgpu_window_priv {
245	Bool variable_refresh;
246};
247
248extern DevScreenPrivateKeyRec amdgpu_device_private_key;
249
250typedef struct {
251	EntityInfoPtr pEnt;
252	uint32_t family;
253	struct gbm_device *gbm;
254
255	Bool(*CloseScreen) (ScreenPtr pScreen);
256
257	void (*BlockHandler) (BLOCKHANDLER_ARGS_DECL);
258
259	void (*CreateFence) (ScreenPtr pScreen, struct _SyncFence *pFence,
260			     Bool initially_triggered);
261
262	int pix24bpp;		/* Depth of pixmap for 24bpp fb      */
263	Bool dac6bits;		/* Use 6 bit DAC?                    */
264
265	int pixel_bytes;
266
267	Bool directRenderingEnabled;
268	struct amdgpu_dri2 dri2;
269
270	/* accel */
271	int callback_event_type;
272	uint_fast32_t gpu_flushed;
273	uint_fast32_t gpu_synced;
274	Bool use_glamor;
275	Bool force_accel;
276	Bool shadow_primary;
277	Bool vrr_support;
278	int tear_free;
279
280	/* general */
281	OptionInfoPtr Options;
282
283	DisplayModePtr currentMode;
284
285	CreateScreenResourcesProcPtr CreateScreenResources;
286	CreateWindowProcPtr CreateWindow;
287	WindowExposuresProcPtr WindowExposures;
288	miPointerSpriteFuncPtr SpriteFuncs;
289
290	/* Number of SW cursors currently visible on this screen */
291	int sprites_visible;
292
293	int instance_id;
294
295	Bool shadow_fb;
296	void *fb_shadow;
297	struct amdgpu_buffer *front_buffer;
298
299	uint64_t vram_size;
300	uint64_t gart_size;
301	drmmode_rec drmmode;
302	Bool drmmode_inited;
303	/* r6xx+ tile config */
304	Bool have_tiling_info;
305	int group_bytes;
306
307	/* kms pageflipping */
308	WindowPtr flip_window;
309	Bool allowPageFlip;
310	Bool can_async_flip;
311	Bool async_flip_secondaries;
312
313	/* cursor size */
314	int cursor_w;
315	int cursor_h;
316
317	/* If bit n of this field is set, xf86_config->crtc[n] currently can't
318	 * use the HW cursor
319	 */
320	unsigned hwcursor_disabled;
321
322	struct {
323		CreateGCProcPtr SavedCreateGC;
324		RegionPtr (*SavedCopyArea)(DrawablePtr, DrawablePtr, GCPtr,
325					   int, int, int, int, int, int);
326		void (*SavedPolyFillRect)(DrawablePtr, GCPtr, int, xRectangle*);
327		CloseScreenProcPtr SavedCloseScreen;
328		GetImageProcPtr SavedGetImage;
329		GetSpansProcPtr SavedGetSpans;
330		CreatePixmapProcPtr SavedCreatePixmap;
331		DestroyPixmapProcPtr SavedDestroyPixmap;
332		CopyWindowProcPtr SavedCopyWindow;
333		ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
334		BitmapToRegionProcPtr SavedBitmapToRegion;
335#ifdef RENDER
336		CompositeProcPtr SavedComposite;
337		TrianglesProcPtr SavedTriangles;
338		GlyphsProcPtr SavedGlyphs;
339		TrapezoidsProcPtr SavedTrapezoids;
340		AddTrapsProcPtr SavedAddTraps;
341		UnrealizeGlyphProcPtr SavedUnrealizeGlyph;
342#endif
343		SharePixmapBackingProcPtr SavedSharePixmapBacking;
344		SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking;
345	} glamor;
346
347	xf86CrtcFuncsRec drmmode_crtc_funcs;
348} AMDGPUInfoRec, *AMDGPUInfoPtr;
349
350
351/* amdgpu_dri3.c */
352Bool amdgpu_dri3_screen_init(ScreenPtr screen);
353
354/* amdgpu_kms.c */
355Bool amdgpu_window_has_variable_refresh(WindowPtr win);
356Bool amdgpu_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id,
357			      PixmapPtr src_pix, BoxRec extents);
358void AMDGPUWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion
359#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0)
360				   , RegionPtr pBSRegion
361#endif
362				   );
363
364/* amdgpu_present.c */
365void amdgpu_present_set_screen_vrr(ScrnInfoPtr scrn, Bool vrr_enabled);
366Bool amdgpu_present_screen_init(ScreenPtr screen);
367
368/* amdgpu_sync.c */
369extern Bool amdgpu_sync_init(ScreenPtr screen);
370extern void amdgpu_sync_close(ScreenPtr screen);
371
372/* amdgpu_video.c */
373extern void AMDGPUInitVideo(ScreenPtr pScreen);
374extern void AMDGPUResetVideo(ScrnInfoPtr pScrn);
375extern xf86CrtcPtr amdgpu_pick_best_crtc(ScreenPtr pScreen,
376					 int x1, int x2, int y1, int y2);
377extern RRCrtcPtr amdgpu_randr_crtc_covering_drawable(DrawablePtr pDraw);
378
379extern AMDGPUEntPtr AMDGPUEntPriv(ScrnInfoPtr pScrn);
380
381#endif /* _AMDGPU_DRV_H_ */
382