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 _RADEON_H_
38 #define _RADEON_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 "exa.h"
53 
54 				/* Exa and 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 "radeon_probe.h"
64 
65 				/* DRI support */
66 #include "xf86drm.h"
67 #include "radeon_drm.h"
68 
69 #ifndef RADEON_GEM_NO_CPU_ACCESS
70 #define RADEON_GEM_NO_CPU_ACCESS	(1 << 4)
71 #endif
72 
73 #ifdef DAMAGE
74 #include "damage.h"
75 #include "globals.h"
76 #endif
77 
78 #include "xf86Crtc.h"
79 #include "X11/Xatom.h"
80 
81 #include "radeon_bo.h"
82 #include "radeon_cs.h"
83 #include "radeon_dri2.h"
84 #include "drmmode_display.h"
85 #include "radeon_surface.h"
86 #include "radeon_bo_helper.h"
87 
88 				/* Render support */
89 #ifdef RENDER
90 #include "picturestr.h"
91 #endif
92 
93 #include "compat-api.h"
94 
95 #include "simple_list.h"
96 #include "atipcirename.h"
97 
98 struct _SyncFence;
99 
100 #ifndef HAVE_REGIONDUPLICATE
101 
102 static inline RegionPtr
RegionDuplicate(RegionPtr pOld)103 RegionDuplicate(RegionPtr pOld)
104 {
105     RegionPtr pNew;
106 
107     pNew = RegionCreate(&pOld->extents, 0);
108     if (!pNew)
109 	return NULL;
110     if (!RegionCopy(pNew, pOld)) {
111 	RegionDestroy(pNew);
112 	return NULL;
113     }
114     return pNew;
115 }
116 
117 #endif
118 
119 #ifndef MAX
120 #define MAX(a,b) ((a)>(b)?(a):(b))
121 #endif
122 #ifndef MIN
123 #define MIN(a,b) ((a)>(b)?(b):(a))
124 #endif
125 
126 #if HAVE_BYTESWAP_H
127 #include <byteswap.h>
128 #elif defined(USE_SYS_ENDIAN_H)
129 #include <sys/endian.h>
130 #else
131 #define bswap_16(value)  \
132         ((((value) & 0xff) << 8) | ((value) >> 8))
133 
134 #define bswap_32(value) \
135         (((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \
136         (uint32_t)bswap_16((uint16_t)((value) >> 16)))
137 
138 #define bswap_64(value) \
139         (((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) \
140             << 32) | \
141         (uint64_t)bswap_32((uint32_t)((value) >> 32)))
142 #endif
143 
144 #if X_BYTE_ORDER == X_BIG_ENDIAN
145 #define le32_to_cpu(x) bswap_32(x)
146 #define le16_to_cpu(x) bswap_16(x)
147 #define cpu_to_le32(x) bswap_32(x)
148 #define cpu_to_le16(x) bswap_16(x)
149 #else
150 #define le32_to_cpu(x) (x)
151 #define le16_to_cpu(x) (x)
152 #define cpu_to_le32(x) (x)
153 #define cpu_to_le16(x) (x)
154 #endif
155 
156 /* Provide substitutes for gcc's __FUNCTION__ on other compilers */
157 #if !defined(__GNUC__) && !defined(__FUNCTION__)
158 # define __FUNCTION__ __func__		/* C99 */
159 #endif
160 
161 typedef enum {
162     OPTION_ACCEL,
163     OPTION_SW_CURSOR,
164     OPTION_PAGE_FLIP,
165     OPTION_EXA_PIXMAPS,
166     OPTION_COLOR_TILING,
167     OPTION_COLOR_TILING_2D,
168 #ifdef RENDER
169     OPTION_RENDER_ACCEL,
170     OPTION_SUBPIXEL_ORDER,
171 #endif
172     OPTION_ACCELMETHOD,
173     OPTION_EXA_VSYNC,
174     OPTION_ZAPHOD_HEADS,
175     OPTION_SWAPBUFFERS_WAIT,
176     OPTION_DELETE_DP12,
177     OPTION_DRI3,
178     OPTION_DRI,
179     OPTION_SHADOW_PRIMARY,
180     OPTION_TEAR_FREE,
181 } RADEONOpts;
182 
183 
184 static inline ScreenPtr
radeon_master_screen(ScreenPtr screen)185 radeon_master_screen(ScreenPtr screen)
186 {
187     if (screen->current_master)
188 	return screen->current_master;
189 
190     return screen;
191 }
192 
193 static inline ScreenPtr
radeon_dirty_master(PixmapDirtyUpdatePtr dirty)194 radeon_dirty_master(PixmapDirtyUpdatePtr dirty)
195 {
196     return radeon_master_screen(dirty->slave_dst->drawable.pScreen);
197 }
198 
199 static inline DrawablePtr
radeon_dirty_src_drawable(PixmapDirtyUpdatePtr dirty)200 radeon_dirty_src_drawable(PixmapDirtyUpdatePtr dirty)
201 {
202 #ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC
203     return dirty->src;
204 #else
205     return &dirty->src->drawable;
206 #endif
207 }
208 
209 static inline Bool
radeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty,PixmapPtr pixmap)210 radeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap)
211 {
212     return radeon_dirty_src_drawable(dirty) == &pixmap->drawable;
213 }
214 
215 
216 #define RADEON_VSYNC_TIMEOUT	20000 /* Maximum wait for VSYNC (in usecs) */
217 
218 /* Buffer are aligned on 4096 byte boundaries */
219 #define RADEON_GPU_PAGE_SIZE 4096
220 #define RADEON_BUFFER_ALIGN (RADEON_GPU_PAGE_SIZE - 1)
221 
222 
223 #define xFixedToFloat(f) (((float) (f)) / 65536)
224 
225 #define RADEON_LOGLEVEL_DEBUG 4
226 
227 /* for Xv, outputs */
228 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
229 
230 /* Other macros */
231 #define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
232 #define RADEONPTR(pScrn)      ((RADEONInfoPtr)(pScrn)->driverPrivate)
233 
234 #define IS_RV100_VARIANT ((info->ChipFamily == CHIP_FAMILY_RV100)  ||  \
235         (info->ChipFamily == CHIP_FAMILY_RV200)  ||  \
236         (info->ChipFamily == CHIP_FAMILY_RS100)  ||  \
237         (info->ChipFamily == CHIP_FAMILY_RS200)  ||  \
238         (info->ChipFamily == CHIP_FAMILY_RV250)  ||  \
239         (info->ChipFamily == CHIP_FAMILY_RV280)  ||  \
240         (info->ChipFamily == CHIP_FAMILY_RS300))
241 
242 
243 #define IS_R300_VARIANT ((info->ChipFamily == CHIP_FAMILY_R300)  ||  \
244         (info->ChipFamily == CHIP_FAMILY_RV350) ||  \
245         (info->ChipFamily == CHIP_FAMILY_R350)  ||  \
246         (info->ChipFamily == CHIP_FAMILY_RV380) ||  \
247         (info->ChipFamily == CHIP_FAMILY_R420)  ||  \
248         (info->ChipFamily == CHIP_FAMILY_RV410) ||  \
249         (info->ChipFamily == CHIP_FAMILY_RS400) ||  \
250         (info->ChipFamily == CHIP_FAMILY_RS480))
251 
252 #define IS_AVIVO_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV515))
253 
254 #define IS_DCE3_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV620))
255 
256 #define IS_DCE32_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV730))
257 
258 #define IS_DCE4_VARIANT ((info->ChipFamily >= CHIP_FAMILY_CEDAR))
259 
260 #define IS_DCE41_VARIANT ((info->ChipFamily >= CHIP_FAMILY_PALM))
261 
262 #define IS_DCE5_VARIANT ((info->ChipFamily >= CHIP_FAMILY_BARTS))
263 
264 #define IS_EVERGREEN_3D (info->ChipFamily >= CHIP_FAMILY_CEDAR)
265 
266 #define IS_R600_3D (info->ChipFamily >= CHIP_FAMILY_R600)
267 
268 #define IS_R500_3D ((info->ChipFamily == CHIP_FAMILY_RV515)  ||  \
269 	(info->ChipFamily == CHIP_FAMILY_R520)   ||  \
270 	(info->ChipFamily == CHIP_FAMILY_RV530)  ||  \
271 	(info->ChipFamily == CHIP_FAMILY_R580)   ||  \
272 	(info->ChipFamily == CHIP_FAMILY_RV560)  ||  \
273 	(info->ChipFamily == CHIP_FAMILY_RV570))
274 
275 /* RS6xx, RS740 are technically R4xx as well, but the
276  * clipping hardware seems to follow the r3xx restrictions
277  */
278 #define IS_R400_3D ((info->ChipFamily == CHIP_FAMILY_R420)  ||  \
279 	(info->ChipFamily == CHIP_FAMILY_RV410))
280 
281 #define IS_R300_3D ((info->ChipFamily == CHIP_FAMILY_R300)  ||  \
282 	(info->ChipFamily == CHIP_FAMILY_RV350) ||  \
283 	(info->ChipFamily == CHIP_FAMILY_R350)  ||  \
284 	(info->ChipFamily == CHIP_FAMILY_RV380) ||  \
285 	(info->ChipFamily == CHIP_FAMILY_R420)  ||  \
286 	(info->ChipFamily == CHIP_FAMILY_RV410) ||  \
287 	(info->ChipFamily == CHIP_FAMILY_RS690) ||  \
288 	(info->ChipFamily == CHIP_FAMILY_RS600) ||  \
289 	(info->ChipFamily == CHIP_FAMILY_RS740) ||  \
290 	(info->ChipFamily == CHIP_FAMILY_RS400) ||  \
291 	(info->ChipFamily == CHIP_FAMILY_RS480))
292 
293 #define IS_R200_3D ((info->ChipFamily == CHIP_FAMILY_RV250) || \
294 	(info->ChipFamily == CHIP_FAMILY_RV280) || \
295 	(info->ChipFamily == CHIP_FAMILY_RS300) || \
296 	(info->ChipFamily == CHIP_FAMILY_R200))
297 
298 #define CURSOR_WIDTH	64
299 #define CURSOR_HEIGHT	64
300 
301 #define CURSOR_WIDTH_CIK	128
302 #define CURSOR_HEIGHT_CIK	128
303 
304 #ifdef USE_GLAMOR
305 
306 struct radeon_pixmap {
307 	uint_fast32_t gpu_read;
308 	uint_fast32_t gpu_write;
309 
310 	struct radeon_buffer *bo;
311 	struct drmmode_fb *fb;
312 	Bool fb_failed;
313 
314 	uint32_t tiling_flags;
315 
316 	/* GEM handle for glamor-only pixmaps shared via DRI3 */
317 	Bool handle_valid;
318 	uint32_t handle;
319 };
320 
321 extern DevPrivateKeyRec glamor_pixmap_index;
322 
radeon_get_pixmap_private(PixmapPtr pixmap)323 static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap)
324 {
325 	return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
326 }
327 
radeon_set_pixmap_private(PixmapPtr pixmap,struct radeon_pixmap * priv)328 static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pixmap *priv)
329 {
330 	dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_index, priv);
331 }
332 
333 #endif /* USE_GLAMOR */
334 
335 
336 struct radeon_exa_pixmap_priv {
337     struct radeon_buffer *bo;
338     struct drmmode_fb *fb;
339     uint32_t tiling_flags;
340     struct radeon_surface surface;
341     Bool bo_mapped;
342     Bool shared;
343 };
344 
345 #define RADEON_2D_EXA_COPY 1
346 #define RADEON_2D_EXA_SOLID 2
347 
348 struct radeon_2d_state {
349     int op; //
350     uint32_t dst_pitch_offset;
351     uint32_t src_pitch_offset;
352     uint32_t dp_gui_master_cntl;
353     uint32_t dp_cntl;
354     uint32_t dp_write_mask;
355     uint32_t dp_brush_frgd_clr;
356     uint32_t dp_brush_bkgd_clr;
357     uint32_t dp_src_frgd_clr;
358     uint32_t dp_src_bkgd_clr;
359     uint32_t default_sc_bottom_right;
360     uint32_t dst_domain;
361     struct radeon_bo *dst_bo;
362     struct radeon_bo *src_bo;
363 };
364 
365 #define DMA_BO_FREE_TIME 1000
366 
367 struct radeon_dma_bo {
368     struct radeon_dma_bo *next, *prev;
369     struct radeon_bo  *bo;
370     int expire_counter;
371 };
372 
373 struct r600_accel_object {
374     uint32_t pitch;
375     uint32_t width;
376     uint32_t height;
377     int bpp;
378     uint32_t domain;
379     struct radeon_bo *bo;
380     uint32_t tiling_flags;
381     struct radeon_surface *surface;
382 };
383 
384 struct radeon_vbo_object {
385     int               vb_offset;
386     int               vb_total;
387     uint32_t          vb_size;
388     uint32_t          vb_op_vert_size;
389     int32_t           vb_start_op;
390     struct radeon_bo *vb_bo;
391     unsigned          verts_per_op;
392 };
393 
394 struct radeon_accel_state {
395 
396 				/* Saved values for ScreenToScreenCopy */
397     int               xdir;
398     int               ydir;
399 
400     /* render accel */
401     unsigned short    texW[2];
402     unsigned short    texH[2];
403     Bool              XInited3D; /* X itself has the 3D context */
404     int               num_gb_pipes;
405     Bool              has_tcl;
406     Bool              allowHWDFS;
407 
408     /* EXA */
409     ExaDriverPtr      exa;
410     int               exaSyncMarker;
411     int               exaMarkerSynced;
412     int               engineMode;
413 #define EXA_ENGINEMODE_UNKNOWN 0
414 #define EXA_ENGINEMODE_2D      1
415 #define EXA_ENGINEMODE_3D      2
416 
417     int               composite_op;
418     PicturePtr        dst_pic;
419     PicturePtr        msk_pic;
420     PicturePtr        src_pic;
421     PixmapPtr         dst_pix;
422     PixmapPtr         msk_pix;
423     PixmapPtr         src_pix;
424     Bool              is_transform[2];
425     PictTransform     *transform[2];
426     /* Whether we are tiling horizontally and vertically */
427     Bool              need_src_tile_x;
428     Bool              need_src_tile_y;
429     /* Size of tiles ... set to 65536x65536 if not tiling in that direction */
430     Bool              src_tile_width;
431     Bool              src_tile_height;
432     uint32_t          *draw_header;
433     unsigned          vtx_count;
434     unsigned          num_vtx;
435     Bool              vsync;
436 
437     struct radeon_vbo_object vbo;
438     struct radeon_vbo_object cbuf;
439 
440     /* where to discard IB from if we cancel operation */
441     uint32_t          ib_reset_op;
442     struct radeon_dma_bo bo_free;
443     struct radeon_dma_bo bo_wait;
444     struct radeon_dma_bo bo_reserved;
445     Bool use_vbos;
446     void (*finish_op)(ScrnInfoPtr, int);
447     // shader storage
448     struct radeon_bo  *shaders_bo;
449     uint32_t          solid_vs_offset;
450     uint32_t          solid_ps_offset;
451     uint32_t          copy_vs_offset;
452     uint32_t          copy_ps_offset;
453     uint32_t          comp_vs_offset;
454     uint32_t          comp_ps_offset;
455     uint32_t          xv_vs_offset;
456     uint32_t          xv_ps_offset;
457     // shader consts
458     uint32_t          solid_vs_const_offset;
459     uint32_t          solid_ps_const_offset;
460     uint32_t          copy_vs_const_offset;
461     uint32_t          copy_ps_const_offset;
462     uint32_t          comp_vs_const_offset;
463     uint32_t          comp_ps_const_offset;
464     uint32_t          comp_mask_ps_const_offset;
465     uint32_t          xv_vs_const_offset;
466     uint32_t          xv_ps_const_offset;
467 
468     //size/addr stuff
469     struct r600_accel_object src_obj[2];
470     struct r600_accel_object dst_obj;
471     uint32_t          src_size[2];
472     uint32_t          dst_size;
473 
474     uint32_t          vs_size;
475     uint64_t          vs_mc_addr;
476     uint32_t          ps_size;
477     uint64_t          ps_mc_addr;
478 
479     // solid/copy
480     void *copy_area;
481     struct radeon_bo  *copy_area_bo;
482     Bool              same_surface;
483     int               rop;
484     uint32_t          planemask;
485     uint32_t          fg;
486 
487     // composite
488     Bool              component_alpha;
489     Bool              src_alpha;
490     // vline
491     xf86CrtcPtr       vline_crtc;
492     int               vline_y1;
493     int               vline_y2;
494 
495     Bool              force;
496 };
497 
498 struct radeon_client_priv {
499     uint_fast32_t     needs_flush;
500 };
501 
502 struct radeon_device_priv {
503     CursorPtr cursor;
504     Bool sprite_visible;
505 };
506 
507 extern DevScreenPrivateKeyRec radeon_device_private_key;
508 
509 typedef struct {
510     EntityInfoPtr     pEnt;
511     pciVideoPtr       PciInfo;
512     int               Chipset;
513     RADEONChipFamily  ChipFamily;
514 
515     Bool              (*CloseScreen)(ScreenPtr pScreen);
516 
517     void              (*BlockHandler)(BLOCKHANDLER_ARGS_DECL);
518 
519     void              (*CreateFence) (ScreenPtr pScreen, struct _SyncFence *pFence,
520 				      Bool initially_triggered);
521 
522     int               pix24bpp;         /* Depth of pixmap for 24bpp fb      */
523     Bool              dac6bits;         /* Use 6 bit DAC?                    */
524 
525     int               pixel_bytes;
526 
527     Bool              directRenderingEnabled;
528     struct radeon_dri2  dri2;
529 
530     /* accel */
531     Bool              RenderAccel; /* Render */
532     Bool              allowColorTiling;
533     Bool              allowColorTiling2D;
534     int               callback_event_type;
535     uint_fast32_t     gpu_flushed;
536     uint_fast32_t     gpu_synced;
537     struct radeon_accel_state *accel_state;
538     PixmapPtr         fbcon_pixmap;
539     Bool              accelOn;
540     Bool              use_glamor;
541     Bool              shadow_primary;
542     int               tear_free;
543     Bool	      exa_pixmaps;
544     Bool              exa_force_create;
545     XF86ModReqInfo    exaReq;
546     Bool              is_fast_fb; /* use direct mapping for fast fb access */
547 
548     unsigned int xv_max_width;
549     unsigned int xv_max_height;
550 
551     /* general */
552     OptionInfoPtr     Options;
553 
554     DisplayModePtr currentMode;
555 
556     CreateScreenResourcesProcPtr CreateScreenResources;
557     CreateWindowProcPtr CreateWindow;
558     WindowExposuresProcPtr WindowExposures;
559     miPointerSpriteFuncPtr SpriteFuncs;
560 
561     /* Number of SW cursors currently visible on this screen */
562     int sprites_visible;
563 
564     int instance_id;
565 
566     Bool              r600_shadow_fb;
567     void *fb_shadow;
568 
569     void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB
570     struct radeon_2d_state state_2d;
571     struct radeon_buffer *front_buffer;
572     struct radeon_bo_manager *bufmgr;
573     struct radeon_cs_manager *csm;
574     struct radeon_cs *cs;
575 
576     uint64_t vram_size;
577     uint64_t gart_size;
578     drmmode_rec drmmode;
579     Bool drmmode_inited;
580     /* r6xx+ tile config */
581     Bool have_tiling_info;
582     uint32_t tile_config;
583     int group_bytes;
584     int num_channels;
585     int num_banks;
586     int r7xx_bank_op;
587     struct radeon_surface_manager *surf_man;
588     struct radeon_surface front_surface;
589 
590     /* Xv bicubic filtering */
591     struct radeon_bo *bicubic_bo;
592 
593     /* kms pageflipping */
594     Bool allowPageFlip;
595 
596     /* Perform vsync'ed SwapBuffers? */
597     Bool swapBuffersWait;
598 
599     /* cursor size */
600     int cursor_w;
601     int cursor_h;
602 
603     /* If bit n of this field is set, xf86_config->crtc[n] currently can't
604      * use the HW cursor
605      */
606     unsigned hwcursor_disabled;
607 
608 #ifdef USE_GLAMOR
609     struct gbm_device *gbm;
610 
611     struct {
612 	CreateGCProcPtr SavedCreateGC;
613 	RegionPtr (*SavedCopyArea)(DrawablePtr, DrawablePtr, GCPtr, int, int,
614 				   int, int, int, int);
615 	void (*SavedPolyFillRect)(DrawablePtr, GCPtr, int, xRectangle*);
616 	CloseScreenProcPtr SavedCloseScreen;
617 	GetImageProcPtr SavedGetImage;
618 	GetSpansProcPtr SavedGetSpans;
619 	CreatePixmapProcPtr SavedCreatePixmap;
620 	DestroyPixmapProcPtr SavedDestroyPixmap;
621 	CopyWindowProcPtr SavedCopyWindow;
622 	ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
623 	BitmapToRegionProcPtr SavedBitmapToRegion;
624 #ifdef RENDER
625 	CompositeProcPtr SavedComposite;
626 	TrianglesProcPtr SavedTriangles;
627 	GlyphsProcPtr SavedGlyphs;
628 	TrapezoidsProcPtr SavedTrapezoids;
629 	AddTrapsProcPtr SavedAddTraps;
630 	UnrealizeGlyphProcPtr SavedUnrealizeGlyph;
631 #endif
632 	SharePixmapBackingProcPtr SavedSharePixmapBacking;
633 	SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking;
634     } glamor;
635 #endif /* USE_GLAMOR */
636 
637     xf86CrtcFuncsRec drmmode_crtc_funcs;
638 } RADEONInfoRec, *RADEONInfoPtr;
639 
640 /* radeon_accel.c */
641 extern Bool RADEONAccelInit(ScreenPtr pScreen);
642 extern void RADEONEngineInit(ScrnInfoPtr pScrn);
643 extern void  RADEONCopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap);
644 extern void RADEONInit3DEngine(ScrnInfoPtr pScrn);
645 extern int radeon_cs_space_remaining(ScrnInfoPtr pScrn);
646 
647 /* radeon_bo_helper.c */
648 extern Bool
649 radeon_surface_initialize(RADEONInfoPtr info, struct radeon_surface *surface,
650 			  int width, int height, int cpp, uint32_t tiling_flags,
651 			  int usage_hint);
652 
653 extern Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle);
654 
655 /* radeon_commonfuncs.c */
656 extern void RADEONWaitForVLine(ScrnInfoPtr pScrn, PixmapPtr pPix,
657 			       xf86CrtcPtr crtc, int start, int stop);
658 
659 
660 /* radeon_exa.c */
661 extern unsigned eg_tile_split(unsigned tile_split);
662 extern Bool radeon_transform_is_affine_or_scaled(PictTransformPtr t);
663 
664 /* radeon_exa_funcs.c */
665 extern Bool RADEONDrawInit(ScreenPtr pScreen);
666 extern Bool R600DrawInit(ScreenPtr pScreen);
667 extern Bool R600LoadShaders(ScrnInfoPtr pScrn);
668 extern Bool EVERGREENDrawInit(ScreenPtr pScreen);
669 
670 /* radeon_exa.c */
671 extern Bool RADEONGetDatatypeBpp(int bpp, uint32_t *type);
672 extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
673 				       uint32_t *pitch_offset);
674 
675 /* radeon_dri3.c */
676 Bool radeon_dri3_screen_init(ScreenPtr screen);
677 
678 /* radeon_kms.c */
679 Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id,
680 			      PixmapPtr src_pix, BoxRec extents);
681 void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion
682 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0)
683 				   , RegionPtr pBSRegion
684 #endif
685 				   );
686 
687 /* radeon_present.c */
688 Bool radeon_present_screen_init(ScreenPtr screen);
689 
690 /* radeon_sync.c */
691 extern Bool radeon_sync_init(ScreenPtr screen);
692 extern void radeon_sync_close(ScreenPtr screen);
693 
694 /* radeon_video.c */
695 extern void RADEONInitVideo(ScreenPtr pScreen);
696 extern void RADEONResetVideo(ScrnInfoPtr pScrn);
697 extern Bool radeon_load_bicubic_texture(ScrnInfoPtr pScrn);
698 extern xf86CrtcPtr radeon_pick_best_crtc(ScrnInfoPtr pScrn,
699 					 Bool consider_disabled,
700 					 int x1, int x2, int y1, int y2);
701 
702 extern void radeon_cs_flush_indirect(ScrnInfoPtr pScrn);
703 extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn,
704 				int num, const char *file,
705 				const char *func, int line);
706 void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size);
707 extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn);
708 
radeon_get_pixmap_surface(PixmapPtr pPix)709 static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix)
710 {
711     struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix);
712 
713     return &driver_priv->surface;
714 }
715 
716 uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix);
717 
radeon_set_pixmap_bo(PixmapPtr pPix,struct radeon_buffer * bo)718 static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_buffer *bo)
719 {
720     ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen);
721     RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
722 #ifdef USE_GLAMOR
723     RADEONInfoPtr info = RADEONPTR(scrn);
724 
725     if (info->use_glamor) {
726 	struct radeon_pixmap *priv;
727 
728 	priv = radeon_get_pixmap_private(pPix);
729 	if (!priv && !bo)
730 	    return TRUE;
731 
732 	if (priv) {
733 	    if (priv->bo) {
734 		if (priv->bo == bo)
735 		    return TRUE;
736 
737 		radeon_buffer_unref(&priv->bo);
738 		priv->handle_valid = FALSE;
739 	    }
740 
741 	    drmmode_fb_reference(pRADEONEnt->fd, &priv->fb, NULL);
742 
743 	    if (!bo) {
744 		free(priv);
745 		priv = NULL;
746 	    }
747 	}
748 
749 	if (bo) {
750 	    if (!priv) {
751 		priv = calloc(1, sizeof (struct radeon_pixmap));
752 		if (!priv)
753 		    return FALSE;
754 	    }
755 
756 	    radeon_buffer_ref(bo);
757 	    priv->bo = bo;
758 	}
759 
760 	radeon_set_pixmap_private(pPix, priv);
761 	radeon_get_pixmap_tiling_flags(pPix);
762 	return TRUE;
763     } else
764 #endif /* USE_GLAMOR */
765     {
766 	struct radeon_exa_pixmap_priv *driver_priv;
767 
768 	driver_priv = exaGetPixmapDriverPrivate(pPix);
769 	if (driver_priv) {
770 	    uint32_t pitch;
771 
772 	    radeon_buffer_unref(&driver_priv->bo);
773 	    drmmode_fb_reference(pRADEONEnt->fd, &driver_priv->fb, NULL);
774 
775 	    driver_priv->bo = bo;
776 
777 	    if (bo) {
778 		radeon_buffer_ref(bo);
779 		radeon_bo_get_tiling(bo->bo.radeon, &driver_priv->tiling_flags,
780 				     &pitch);
781 	    } else
782 		driver_priv->tiling_flags = 0;
783 
784 	    return TRUE;
785 	}
786 
787 	return FALSE;
788     }
789 }
790 
radeon_get_pixmap_bo(PixmapPtr pPix)791 static inline struct radeon_buffer *radeon_get_pixmap_bo(PixmapPtr pPix)
792 {
793     RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
794 #ifdef USE_GLAMOR
795 
796     if (info->use_glamor) {
797 	struct radeon_pixmap *priv;
798 	priv = radeon_get_pixmap_private(pPix);
799 	return priv ? priv->bo : NULL;
800     } else
801 #endif
802     if (info->accelOn) {
803 	struct radeon_exa_pixmap_priv *driver_priv;
804 	driver_priv = exaGetPixmapDriverPrivate(pPix);
805 	return driver_priv ? driver_priv->bo : NULL;
806     }
807 
808     return NULL;
809 }
810 
radeon_get_pixmap_shared(PixmapPtr pPix)811 static inline Bool radeon_get_pixmap_shared(PixmapPtr pPix)
812 {
813 #ifdef USE_GLAMOR
814     RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
815 
816     if (info->use_glamor) {
817         ErrorF("glamor sharing todo\n");
818 	return FALSE;
819     } else
820 #endif
821     {
822 	struct radeon_exa_pixmap_priv *driver_priv;
823 	driver_priv = exaGetPixmapDriverPrivate(pPix);
824 	return driver_priv->shared;
825     }
826     return FALSE;
827 }
828 
829 static inline struct drmmode_fb*
radeon_fb_create(ScrnInfoPtr scrn,int drm_fd,uint32_t width,uint32_t height,uint32_t pitch,uint32_t handle)830 radeon_fb_create(ScrnInfoPtr scrn, int drm_fd, uint32_t width, uint32_t height,
831 		 uint32_t pitch, uint32_t handle)
832 {
833     struct drmmode_fb *fb  = malloc(sizeof(*fb));
834 
835     if (!fb)
836 	return NULL;
837 
838     fb->refcnt = 1;
839     if (drmModeAddFB(drm_fd, width, height, scrn->depth, scrn->bitsPerPixel,
840 		     pitch, handle, &fb->handle) == 0)
841 	return fb;
842 
843     free(fb);
844     return NULL;
845 }
846 
847 static inline struct drmmode_fb**
radeon_pixmap_get_fb_ptr(PixmapPtr pix)848 radeon_pixmap_get_fb_ptr(PixmapPtr pix)
849 {
850     ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen);
851     RADEONInfoPtr info = RADEONPTR(scrn);
852 
853 #ifdef USE_GLAMOR
854     if (info->use_glamor) {
855 	struct radeon_pixmap *priv = radeon_get_pixmap_private(pix);
856 
857 	if (!priv)
858 	    return NULL;
859 
860 	return &priv->fb;
861     } else
862 #endif
863     if (info->accelOn)
864     {
865 	struct radeon_exa_pixmap_priv *driver_priv =
866 	    exaGetPixmapDriverPrivate(pix);
867 
868 	if (!driver_priv)
869 	    return NULL;
870 
871 	return &driver_priv->fb;
872     }
873 
874     return NULL;
875 }
876 
877 static inline struct drmmode_fb*
radeon_pixmap_get_fb(PixmapPtr pix)878 radeon_pixmap_get_fb(PixmapPtr pix)
879 {
880     struct drmmode_fb **fb_ptr = radeon_pixmap_get_fb_ptr(pix);
881     uint32_t handle;
882 
883     if (fb_ptr && *fb_ptr)
884 	return *fb_ptr;
885 
886     if (radeon_get_pixmap_handle(pix, &handle)) {
887 	ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen);
888 	RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
889 
890 	if (!fb_ptr)
891 	    fb_ptr = radeon_pixmap_get_fb_ptr(pix);
892 
893 	*fb_ptr = radeon_fb_create(scrn, pRADEONEnt->fd,
894 				   pix->drawable.width,
895 				   pix->drawable.height, pix->devKind,
896 				   handle);
897     }
898 
899     return fb_ptr ? *fb_ptr : NULL;
900 }
901 
902 
903 #define CP_PACKET0(reg, n)						\
904 	(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
905 #define CP_PACKET1(reg0, reg1)						\
906 	(RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
907 #define CP_PACKET2()							\
908 	(RADEON_CP_PACKET2)
909 #define CP_PACKET3(pkt, n)						\
910 	(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
911 
912 
913 #define RADEON_VERBOSE	0
914 
915 #define BEGIN_RING(n) do {						\
916     if (RADEON_VERBOSE) {						\
917 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
918 		   "BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\
919     }									\
920     radeon_ddx_cs_start(pScrn, n, __FILE__, __func__, __LINE__);   \
921 } while (0)
922 
923 #define ADVANCE_RING() do {						\
924     radeon_cs_end(info->cs, __FILE__, __func__, __LINE__); \
925   } while (0)
926 
927 #define OUT_RING(x) do {						\
928     if (RADEON_VERBOSE) {						\
929 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
930 		   "   OUT_RING(0x%08x)\n", (unsigned int)(x));		\
931     }									\
932     radeon_cs_write_dword(info->cs, (x));		\
933 } while (0)
934 
935 #define OUT_RING_REG(reg, val)						\
936 do {									\
937     OUT_RING(CP_PACKET0(reg, 0));					\
938     OUT_RING(val);							\
939 } while (0)
940 
941 #define OUT_RING_RELOC(x, read_domains, write_domain)			\
942   do {									\
943 	int _ret; \
944     _ret = radeon_cs_write_reloc(info->cs, x, read_domains, write_domain, 0); \
945 	if (_ret) ErrorF("reloc emit failure %d\n", _ret); \
946   } while(0)
947 
948 
949 #define FLUSH_RING()							\
950 do {									\
951     if (RADEON_VERBOSE)							\
952 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
953 		   "FLUSH_RING in %s\n", __FUNCTION__);			\
954     radeon_cs_flush_indirect(pScrn); 				\
955 } while (0)
956 
957 #define CS_FULL(cs) ((cs)->cdw > 15 * 1024)
958 
959 #define RADEON_SWITCH_TO_2D()						\
960 do {									\
961 	uint32_t flush = 0;                                             \
962 	switch (info->accel_state->engineMode) {			\
963 	case EXA_ENGINEMODE_UNKNOWN:					\
964 	    flush = 1;                                                  \
965 	    break;							\
966 	case EXA_ENGINEMODE_3D:						\
967 	    flush = CS_FULL(info->cs);			\
968 	    break;							\
969 	case EXA_ENGINEMODE_2D:						\
970 	    flush = CS_FULL(info->cs);			\
971 	    break;							\
972 	}								\
973 	if (flush) {							\
974 	    radeon_cs_flush_indirect(pScrn);			\
975 	}								\
976         info->accel_state->engineMode = EXA_ENGINEMODE_2D;              \
977 } while (0);
978 
979 #define RADEON_SWITCH_TO_3D()						\
980 do {									\
981 	uint32_t flush = 0;						\
982 	switch (info->accel_state->engineMode) {			\
983 	case EXA_ENGINEMODE_UNKNOWN:					\
984 	    flush = 1;                                                  \
985 	    break;							\
986 	case EXA_ENGINEMODE_2D:						\
987 	    flush = CS_FULL(info->cs);	 		\
988 	    break;							\
989 	case EXA_ENGINEMODE_3D:						\
990 	    flush = CS_FULL(info->cs);			\
991 	    break;							\
992 	}								\
993 	if (flush) {							\
994 	    radeon_cs_flush_indirect(pScrn);			\
995 	}                                                               \
996 	if (!info->accel_state->XInited3D)				\
997 	    RADEONInit3DEngine(pScrn);                                  \
998         info->accel_state->engineMode = EXA_ENGINEMODE_3D;              \
999 } while (0);
1000 
1001 				/* Memory mapped register access macros */
1002 
1003 #define BEGIN_ACCEL_RELOC(n, r) do {		\
1004 	int _nqw = (n) + (r);	\
1005 	BEGIN_RING(2*_nqw);			\
1006     } while (0)
1007 
1008 #define EMIT_OFFSET(reg, value, pPix, rd, wd) do {		\
1009     driver_priv = exaGetPixmapDriverPrivate(pPix);		\
1010     OUT_RING_REG((reg), (value));				\
1011     OUT_RING_RELOC(driver_priv->bo->bo.radeon, (rd), (wd));	\
1012     } while(0)
1013 
1014 #define EMIT_READ_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT), 0)
1015 #define EMIT_WRITE_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, 0, RADEON_GEM_DOMAIN_VRAM)
1016 
1017 #define OUT_TEXTURE_REG(reg, offset, bo) do {   \
1018     OUT_RING_REG((reg), (offset));                                   \
1019     OUT_RING_RELOC((bo), RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); \
1020   } while(0)
1021 
1022 #define EMIT_COLORPITCH(reg, value, pPix) do {			\
1023     driver_priv = exaGetPixmapDriverPrivate(pPix);			\
1024     OUT_RING_REG((reg), value);					\
1025     OUT_RING_RELOC(driver_priv->bo->bo.radeon, 0, RADEON_GEM_DOMAIN_VRAM);	\
1026 } while(0)
1027 
RADEON_SYNC(RADEONInfoPtr info,ScrnInfoPtr pScrn)1028 static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn)
1029 {
1030     if (pScrn->pScreen)
1031 	exaWaitSync(pScrn->pScreen);
1032 }
1033 
1034 enum {
1035     RADEON_CREATE_PIXMAP_SCANOUT		= 0x02000000,
1036     RADEON_CREATE_PIXMAP_DRI2			= 0x04000000,
1037     RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE	= 0x08000000,
1038     RADEON_CREATE_PIXMAP_TILING_MACRO		= 0x10000000,
1039     RADEON_CREATE_PIXMAP_TILING_MICRO		= 0x20000000,
1040     RADEON_CREATE_PIXMAP_DEPTH			= 0x40000000, /* for r200 */
1041     RADEON_CREATE_PIXMAP_SZBUFFER		= 0x80000000, /* for eg */
1042 };
1043 
1044 #define RADEON_CREATE_PIXMAP_TILING_FLAGS	\
1045     (RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE |	\
1046      RADEON_CREATE_PIXMAP_TILING_MACRO |	\
1047      RADEON_CREATE_PIXMAP_TILING_MICRO |	\
1048      RADEON_CREATE_PIXMAP_DEPTH |		\
1049      RADEON_CREATE_PIXMAP_SZBUFFER)
1050 
1051 
1052 /* Compute log base 2 of val. */
1053 static __inline__ int
RADEONLog2(int val)1054 RADEONLog2(int val)
1055 {
1056 	return 31 - __builtin_clz(val);
1057 }
1058 
1059 #define RADEON_TILING_MASK				0xff
1060 #define RADEON_TILING_LINEAR				0x0
1061 
1062 #endif /* _RADEON_H_ */
1063