1 /*
2  * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
3  *                      Precision Insight, Inc., Cedar Park, Texas, and
4  *                      VA Linux Systems Inc., Fremont, California.
5  *
6  * All Rights Reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining
9  * a copy of this software and associated documentation files (the
10  * "Software"), to deal in the Software without restriction, including
11  * without limitation on the rights to use, copy, modify, merge,
12  * publish, distribute, sublicense, and/or sell copies of the Software,
13  * and to permit persons to whom the Software is furnished to do so,
14  * subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice (including the
17  * next paragraph) shall be included in all copies or substantial
18  * portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, PRECISION INSIGHT, VA LINUX
24  * SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  * OTHER DEALINGS IN THE SOFTWARE.
28  */
29 
30 /*
31  * Authors:
32  *   Rickard E. Faith <faith@valinux.com>
33  *   Kevin E. Martin <martin@valinux.com>
34  *
35  */
36 
37 #ifndef _R128_H_
38 #define _R128_H_
39 
40 #include <unistd.h>
41 #include "xf86str.h"
42 
43 				/* PCI support */
44 #include "xf86Pci.h"
45 
46 				/* EXA support */
47 #ifdef USE_EXA
48 #include "exa.h"
49 #endif
50 
51 				/* XAA and Cursor Support */
52 #ifdef HAVE_XAA_H
53 #include "xaa.h"
54 #endif
55 #include "xf86fbman.h"
56 #include "xf86Cursor.h"
57 
58 				/* DDC support */
59 #include "xf86DDC.h"
60 
61 				/* Xv support */
62 #include "xf86xv.h"
63 
64 				/* DRI support */
65 #ifndef XF86DRI
66 #undef R128DRI
67 #endif
68 
69 #if R128DRI
70 #define _XF86DRI_SERVER_
71 #include "r128_dripriv.h"
72 #include "dri.h"
73 #endif
74 
75 #include "fb.h"
76 #include "xf86Crtc.h"
77 
78 #include "compat-api.h"
79 #include "atipcirename.h"
80 
81 #include "r128_probe.h"
82 
83 #if HAVE_BYTESWAP_H
84 #include <byteswap.h>
85 #elif defined(USE_SYS_ENDIAN_H)
86 #include <sys/endian.h>
87 #else
88 #define bswap_16(value)  \
89         ((((value) & 0xff) << 8) | ((value) >> 8))
90 
91 #define bswap_32(value) \
92         (((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \
93         (uint32_t)bswap_16((uint16_t)((value) >> 16)))
94 
95 #define bswap_64(value) \
96         (((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) \
97             << 32) | \
98         (uint64_t)bswap_32((uint32_t)((value) >> 32)))
99 #endif
100 
101 #if X_BYTE_ORDER == X_BIG_ENDIAN
102 #define le32_to_cpu(x) bswap_32(x)
103 #define le16_to_cpu(x) bswap_16(x)
104 #define cpu_to_le32(x) bswap_32(x)
105 #define cpu_to_le16(x) bswap_16(x)
106 #else
107 #define le32_to_cpu(x) (x)
108 #define le16_to_cpu(x) (x)
109 #define cpu_to_le32(x) (x)
110 #define cpu_to_le16(x) (x)
111 #endif
112 
113 #define R128_DEBUG          0   /* Turn off debugging output               */
114 #define R128_IDLE_RETRY    32   /* Fall out of idle loops after this count */
115 #define R128_TIMEOUT  2000000   /* Fall out of wait loops after this count */
116 #define R128_MMIOSIZE  0x4000
117 
118 #define R128_VBIOS_SIZE 0x00010000
119 
120 #if R128_DEBUG
121 #include "r128_version.h"
122 
123 #endif
124 
125 #if R128_DEBUG
126 #define DEBUG(x) x
127 
128 #else
129 #define DEBUG(x)
130 
131 #endif
132 
133 
134 /* Other macros */
135 #define R128_ARRAY_SIZE(x)  (sizeof(x)/sizeof(x[0]))
136 #define R128_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
137 #define R128PTR(pScrn) ((R128InfoPtr)(pScrn)->driverPrivate)
138 
139 #define R128_BIOS8(v)  ((info->VBIOS[(v)]))
140 #define R128_BIOS16(v) ((info->VBIOS[(v)])           | \
141 			(info->VBIOS[(v) + 1] << 8))
142 #define R128_BIOS32(v) ((info->VBIOS[(v)])           | \
143 			(info->VBIOS[(v) + 1] << 8)  | \
144 			(info->VBIOS[(v) + 2] << 16) | \
145 			(info->VBIOS[(v) + 3] << 24))
146 
147 typedef struct {        /* All values in XCLKS    */
148     int  ML;            /* Memory Read Latency    */
149     int  MB;            /* Memory Burst Length    */
150     int  Trcd;          /* RAS to CAS delay       */
151     int  Trp;           /* RAS percentage         */
152     int  Twr;           /* Write Recovery         */
153     int  CL;            /* CAS Latency            */
154     int  Tr2w;          /* Read to Write Delay    */
155     int  Rloop;         /* Loop Latency           */
156     int  Rloop_fudge;   /* Add to ML to get Rloop */
157     char *name;
158 } R128RAMRec, *R128RAMPtr;
159 
160 typedef struct {
161 				/* Common registers */
162     uint32_t   ovr_clr;
163     uint32_t   ovr_wid_left_right;
164     uint32_t   ovr_wid_top_bottom;
165     uint32_t   ov0_scale_cntl;
166     uint32_t   mpp_tb_config;
167     uint32_t   mpp_gp_config;
168     uint32_t   subpic_cntl;
169     uint32_t   viph_control;
170     uint32_t   i2c_cntl_1;
171     uint32_t   gen_int_cntl;
172     uint32_t   cap0_trig_cntl;
173     uint32_t   cap1_trig_cntl;
174     uint32_t   bus_cntl;
175     uint32_t   config_cntl;
176 
177 				/* Other registers to save for VT switches */
178     uint32_t   dp_datatype;
179     uint32_t   gen_reset_cntl;
180     uint32_t   clock_cntl_index;
181     uint32_t   amcgpio_en_reg;
182     uint32_t   amcgpio_mask;
183 
184 				/* CRTC registers */
185     uint32_t   crtc_gen_cntl;
186     uint32_t   crtc_ext_cntl;
187     uint32_t   dac_cntl;
188     uint32_t   crtc_h_total_disp;
189     uint32_t   crtc_h_sync_strt_wid;
190     uint32_t   crtc_v_total_disp;
191     uint32_t   crtc_v_sync_strt_wid;
192     uint32_t   crtc_offset;
193     uint32_t   crtc_offset_cntl;
194     uint32_t   crtc_pitch;
195 
196 				/* CRTC2 registers */
197     uint32_t   crtc2_gen_cntl;
198     uint32_t   crtc2_h_total_disp;
199     uint32_t   crtc2_h_sync_strt_wid;
200     uint32_t   crtc2_v_total_disp;
201     uint32_t   crtc2_v_sync_strt_wid;
202     uint32_t   crtc2_offset;
203     uint32_t   crtc2_offset_cntl;
204     uint32_t   crtc2_pitch;
205 
206 				/* Flat panel registers */
207     uint32_t   fp_crtc_h_total_disp;
208     uint32_t   fp_crtc_v_total_disp;
209     uint32_t   fp_gen_cntl;
210     uint32_t   fp_h_sync_strt_wid;
211     uint32_t   fp_horz_stretch;
212     uint32_t   fp_panel_cntl;
213     uint32_t   fp_v_sync_strt_wid;
214     uint32_t   fp_vert_stretch;
215     uint32_t   lvds_gen_cntl;
216     uint32_t   tmds_crc;
217     uint32_t   tmds_transmitter_cntl;
218 
219 				/* Computed values for PLL */
220     uint32_t   dot_clock_freq;
221     uint32_t   pll_output_freq;
222     int        feedback_div;
223     int        post_div;
224 
225 				/* PLL registers */
226     uint32_t   ppll_ref_div;
227     uint32_t   ppll_div_3;
228     uint32_t   ppll_div_0;
229     uint32_t   htotal_cntl;
230 
231 				/* Computed values for PLL2 */
232     uint32_t   dot_clock_freq_2;
233     uint32_t   pll_output_freq_2;
234     int        feedback_div_2;
235     int        post_div_2;
236 
237 				/* PLL2 registers */
238     uint32_t   p2pll_ref_div;
239     uint32_t   p2pll_div_0;
240     uint32_t   htotal_cntl2;
241 
242 				/* DDA register */
243     uint32_t   dda_config;
244     uint32_t   dda_on_off;
245 
246 				/* DDA2 register */
247     uint32_t   dda2_config;
248     uint32_t   dda2_on_off;
249 
250 				/* Pallet */
251     Bool       palette_valid;
252     uint32_t   palette[256];
253     uint32_t   palette2[256];
254 } R128SaveRec, *R128SavePtr;
255 
256 typedef struct {
257     uint16_t      reference_freq;
258     uint16_t      reference_div;
259     unsigned      min_pll_freq;
260     unsigned      max_pll_freq;
261     uint16_t      xclk;
262 } R128PLLRec, *R128PLLPtr;
263 
264 typedef struct {
265     int                bitsPerPixel;
266     int                depth;
267     int                displayWidth;
268     int                pixel_code;
269     int                pixel_bytes;
270     DisplayModePtr     mode;
271 } R128FBLayout;
272 
273 #ifdef USE_EXA
274 struct r128_2d_state {
275     Bool in_use;
276     Bool composite_setup;
277     uint32_t dst_pitch_offset;
278     uint32_t src_pitch_offset;
279     uint32_t dp_gui_master_cntl;
280     uint32_t dp_cntl;
281     uint32_t dp_write_mask;
282     uint32_t dp_brush_frgd_clr;
283     uint32_t dp_brush_bkgd_clr;
284     uint32_t dp_src_frgd_clr;
285     uint32_t dp_src_bkgd_clr;
286     uint32_t default_sc_bottom_right;
287 #if defined(R128DRI) && defined(RENDER)
288     Bool has_mask;
289     int x_offset;
290     int y_offset;
291     int widths[2];
292     int heights[2];
293     Bool is_transform[2];
294     PictTransform *transform[2];
295     PixmapPtr src_pix;
296     PixmapPtr msk_pix;
297 #endif
298 };
299 #endif
300 
301 typedef struct {
302     EntityInfoPtr     pEnt;
303     pciVideoPtr       PciInfo;
304 #ifndef XSERVER_LIBPCIACCESS
305     PCITAG            PciTag;
306 #endif
307     int               Chipset;
308 
309     Bool              FBDev;
310 
311     unsigned long     LinearAddr;   /* Frame buffer physical address         */
312     unsigned long     MMIOAddr;     /* MMIO region physical address          */
313     unsigned long     BIOSAddr;     /* BIOS physical address                 */
314 
315     void              *MMIO;        /* Map of MMIO region                    */
316     void              *FB;          /* Map of frame buffer                   */
317     uint8_t           *VBIOS;       /* Video BIOS for mode validation on FPs */
318     int               FPBIOSstart;  /* Start of the flat panel info          */
319 
320     uint32_t          MemCntl;
321     uint32_t          BusCntl;
322     unsigned long     FbMapSize;    /* Size of frame buffer, in bytes        */
323     Bool              HasPanelRegs; /* Current chip can connect to a FP      */
324 
325     R128PLLRec        pll;
326     R128RAMPtr        ram;
327 
328     R128SaveRec       SavedReg;     /* Original (text) mode                  */
329     R128SaveRec       ModeReg;      /* Current mode                          */
330     Bool              (*CloseScreen)(CLOSE_SCREEN_ARGS_DECL);
331     void              (*BlockHandler)(BLOCKHANDLER_ARGS_DECL);
332 
333     Bool              PaletteSavedOnVT; /* Palette saved on last VT switch   */
334 
335 #ifdef HAVE_XAA_H
336     XAAInfoRecPtr     accel;
337 #endif
338 
339     Bool              noAccel;
340     Bool              accelOn;
341     Bool	      useEXA;
342     Bool	      RenderAccel;
343 #ifdef USE_EXA
344     ExaDriverPtr      ExaDriver;
345     XF86ModReqInfo    exaReq;
346     struct r128_2d_state state_2d;
347 #endif
348 
349     int               fifo_slots;   /* Free slots in the FIFO (64 max)       */
350     int               pix24bpp;     /* Depth of pixmap for 24bpp framebuffer */
351     Bool              dac6bits;     /* Use 6 bit DAC?                        */
352     Bool              swCursor;
353 
354 				/* Computed values for Rage 128 */
355     int               pitch;
356     int               datatype;
357     uint32_t          dp_gui_master_cntl;
358 
359 				/* Saved values for ScreenToScreenCopy */
360     int               xdir;
361     int               ydir;
362 
363 				/* ScanlineScreenToScreenColorExpand support */
364     unsigned char     *scratch_buffer[1];
365     unsigned char     *scratch_save;
366     int               scanline_x;
367     int               scanline_y;
368     int               scanline_w;
369     int               scanline_h;
370 #ifdef R128DRI
371     int               scanline_hpass;
372     int               scanline_x1clip;
373     int               scanline_x2clip;
374     int               scanline_rop;
375     int               scanline_fg;
376     int               scanline_bg;
377 #endif /* R128DRI */
378     int               scanline_words;
379     int               scanline_direct;
380     int               scanline_bpp; /* Only used for ImageWrite */
381 
382     R128FBLayout      CurrentLayout;
383 #ifdef R128DRI
384     Bool              directRenderingEnabled;
385     DRIInfoPtr        pDRIInfo;
386     int               drmFD;
387     drm_context_t     drmCtx;
388 
389     drm_handle_t      fbHandle;
390 
391     drmSize           registerSize;
392     drm_handle_t      registerHandle;
393 
394     Bool              IsPCI;            /* Current card is a PCI card */
395     drmSize           pciSize;
396     drm_handle_t      pciMemHandle;
397     drmAddress        PCI;              /* Map */
398 
399     Bool              allowPageFlip;    /* Enable 3d page flipping */
400     Bool              have3DWindows;    /* Are there any 3d clients? */
401     int               drmMinor;
402 
403     drmSize           agpSize;
404     drm_handle_t      agpMemHandle;     /* Handle from drmAgpAlloc */
405     unsigned long     agpOffset;
406     drmAddress        AGP;              /* Map */
407     int               agpMode;
408 
409     Bool              CCEInUse;         /* CCE is currently active */
410     int               CCEMode;          /* CCE mode that server/clients use */
411     int               CCEFifoSize;      /* Size of the CCE command FIFO */
412     Bool              CCESecure;        /* CCE security enabled */
413     int               CCEusecTimeout;   /* CCE timeout in usecs */
414 
415 				/* CCE ring buffer data */
416     unsigned long     ringStart;        /* Offset into AGP space */
417     drm_handle_t      ringHandle;       /* Handle from drmAddMap */
418     drmSize           ringMapSize;      /* Size of map */
419     int               ringSize;         /* Size of ring (in MB) */
420     drmAddress        ring;             /* Map */
421     int               ringSizeLog2QW;
422 
423     unsigned long     ringReadOffset;   /* Offset into AGP space */
424     drm_handle_t      ringReadPtrHandle;/* Handle from drmAddMap */
425     drmSize           ringReadMapSize;  /* Size of map */
426     drmAddress        ringReadPtr;      /* Map */
427 
428 				/* CCE vertex/indirect buffer data */
429     unsigned long     bufStart;        /* Offset into AGP space */
430     drm_handle_t      bufHandle;       /* Handle from drmAddMap */
431     drmSize           bufMapSize;      /* Size of map */
432     int               bufSize;         /* Size of buffers (in MB) */
433     drmAddress        buf;             /* Map */
434     int               bufNumBufs;      /* Number of buffers */
435     drmBufMapPtr      buffers;         /* Buffer map */
436 
437 				/* CCE AGP Texture data */
438     unsigned long     agpTexStart;      /* Offset into AGP space */
439     drm_handle_t      agpTexHandle;     /* Handle from drmAddMap */
440     drmSize           agpTexMapSize;    /* Size of map */
441     int               agpTexSize;       /* Size of AGP tex space (in MB) */
442     drmAddress        agpTex;           /* Map */
443     int               log2AGPTexGran;
444 
445 				/* CCE 2D accleration */
446     drmBufPtr         indirectBuffer;
447     int               indirectStart;
448 
449 				/* DRI screen private data */
450     int               fbX;
451     int               fbY;
452     int               backX;
453     int               backY;
454     int               depthX;
455     int               depthY;
456 
457     int               frontOffset;
458     int               frontPitch;
459     int               backOffset;
460     int               backPitch;
461     int               depthOffset;
462     int               depthPitch;
463     int               spanOffset;
464     int               textureOffset;
465     int               textureSize;
466     int               log2TexGran;
467 
468 				/* Saved scissor values */
469     uint32_t          sc_left;
470     uint32_t          sc_right;
471     uint32_t          sc_top;
472     uint32_t          sc_bottom;
473 
474     uint32_t          re_top_left;
475     uint32_t          re_width_height;
476 
477     uint32_t          aux_sc_cntl;
478 
479     int               irq;
480     uint32_t          gen_int_cntl;
481 
482     Bool              DMAForXv;
483 #endif
484 
485     XF86VideoAdaptorPtr adaptor;
486     void              (*VideoTimerCallback)(ScrnInfoPtr, Time);
487     int               videoKey;
488     Bool              showCache;
489     OptionInfoPtr     Options;
490 
491     Bool              isDFP;
492     Bool              isPro2;
493     Bool              SwitchingMode;
494     Bool              DDC;
495 
496     Bool              VGAAccess;
497 } R128InfoRec, *R128InfoPtr;
498 
499 #define R128WaitForFifo(pScrn, entries)                                      \
500 do {                                                                         \
501     if (info->fifo_slots < entries) R128WaitForFifoFunction(pScrn, entries); \
502     info->fifo_slots -= entries;                                             \
503 } while (0)
504 
505 /* Compute n/d with rounding. */
R128Div(int n,int d)506 static inline int R128Div(int n, int d)
507 {
508     return (n + (d / 2)) / d;
509 }
510 
511 extern R128EntPtr R128EntPriv(ScrnInfoPtr pScrn);
512 extern void        R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries);
513 extern void        R128WaitForIdle(ScrnInfoPtr pScrn);
514 extern void        R128EngineReset(ScrnInfoPtr pScrn);
515 extern void        R128EngineFlush(ScrnInfoPtr pScrn);
516 
517 extern unsigned    R128INPLL(ScrnInfoPtr pScrn, int addr);
518 extern void        R128WaitForVerticalSync(ScrnInfoPtr pScrn);
519 
520 extern Bool R128XAAAccelInit(ScreenPtr pScreen);
521 extern void        R128EngineInit(ScrnInfoPtr pScrn);
522 extern Bool        R128CursorInit(ScreenPtr pScreen);
523 
524 extern int         R128MinBits(int val);
525 extern xf86OutputPtr R128FirstOutput(xf86CrtcPtr crtc);
526 
527 extern void        R128InitVideo(ScreenPtr pScreen);
528 
529 extern void        R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info);
530 extern void        R128InitRMXRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output, DisplayModePtr mode);
531 extern void        R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output);
532 extern void        R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output);
533 extern void        R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
534 extern void        R128RestoreDACRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
535 extern void        R128RestoreRMXRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
536 extern void        R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
537 extern void        R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
538 extern void        R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
539 extern void        R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
540 extern void        R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
541 extern void        R128RestoreCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr restore);
542 extern void        R128RestorePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr restore);
543 extern void        R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore);
544 
545 extern void        r128_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg);
546 extern void        r128_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y);
547 extern void        r128_crtc_show_cursor(xf86CrtcPtr crtc);
548 extern void        r128_crtc_hide_cursor(xf86CrtcPtr crtc);
549 extern void        r128_crtc_load_cursor_image(xf86CrtcPtr crtc, unsigned char *src);
550 
551 extern uint32_t    R128AllocateMemory(ScrnInfoPtr pScrn, void **mem_struct, int size, int align, Bool need_accel);
552 extern Bool        R128SetupConnectors(ScrnInfoPtr pScrn);
553 extern Bool        R128AllocateControllers(ScrnInfoPtr pScrn);
554 extern void        R128GetPanelInfoFromBIOS(xf86OutputPtr output);
555 extern void        R128Blank(ScrnInfoPtr pScrn);
556 extern void        R128Unblank(ScrnInfoPtr pScrn);
557 extern void        R128DPMSSetOn(xf86OutputPtr output);
558 extern void        R128DPMSSetOff(xf86OutputPtr output);
559 extern ModeStatus     R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags);
560 extern DisplayModePtr R128ProbeOutputModes(xf86OutputPtr output);
561 
562 #ifdef R128DRI
563 extern Bool        R128DRIScreenInit(ScreenPtr pScreen);
564 extern void        R128DRICloseScreen(ScreenPtr pScreen);
565 extern Bool        R128DRIFinishScreenInit(ScreenPtr pScreen);
566 
567 #define R128CCE_START(pScrn, info)					\
568 do {									\
569     int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_START);		\
570     if (_ret) {								\
571 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,				\
572 		   "%s: CCE start %d\n", __FUNCTION__, _ret);		\
573     }									\
574 } while (0)
575 
576 #define R128CCE_STOP(pScrn, info)					\
577 do {									\
578     int _ret = R128CCEStop(pScrn);					\
579     if (_ret) {								\
580 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,				\
581 		   "%s: CCE stop %d\n", __FUNCTION__, _ret);		\
582     }									\
583 } while (0)
584 
585 #define R128CCE_RESET(pScrn, info)					\
586 do {									\
587     if (info->directRenderingEnabled					\
588 	&& R128CCE_USE_RING_BUFFER(info->CCEMode)) {			\
589 	int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_RESET);	\
590 	if (_ret) {							\
591 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,			\
592 		       "%s: CCE reset %d\n", __FUNCTION__, _ret);	\
593 	}								\
594     }									\
595 } while (0)
596 
597 extern drmBufPtr   R128CCEGetBuffer(ScrnInfoPtr pScrn);
598 #endif
599 
600 extern void        R128CCEFlushIndirect(ScrnInfoPtr pScrn, int discard);
601 extern void        R128CCEReleaseIndirect(ScrnInfoPtr pScrn);
602 extern void        R128CCEWaitForIdle(ScrnInfoPtr pScrn);
603 extern int         R128CCEStop(ScrnInfoPtr pScrn);
604 extern void	   R128CopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap);
605 
606 #ifdef USE_EXA
607 extern Bool	   R128EXAInit(ScreenPtr pScreen, int total);
608 extern Bool	   R128GetDatatypeBpp(int bpp, uint32_t *type);
609 extern Bool	   R128GetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset);
610 extern void	   R128DoPrepareCopy(ScrnInfoPtr pScrn, uint32_t src_pitch_offset,
611 				    uint32_t dst_pitch_offset, uint32_t datatype, int alu, Pixel planemask);
612 extern void R128Done(PixmapPtr pPixmap);
613 
614 #ifdef R128DRI
615 extern void EmitCCE2DState(ScrnInfoPtr pScrn);
616 #endif
617 
618 #ifdef RENDER
619 extern Bool R128CCECheckComposite(int op,
620                                     PicturePtr pSrcPicture,
621                                     PicturePtr pMaskPicture,
622                                     PicturePtr pDstPicture);
623 extern Bool R128CCEPrepareComposite(int op,                                    PicturePtr pSrcPicture,
624                                     PicturePtr pMaskPicture,
625                                     PicturePtr pDstPicture,
626                                     PixmapPtr pSrc,
627                                     PixmapPtr pMask,
628                                     PixmapPtr pDst);
629 extern void R128CCEComposite(PixmapPtr pDst,
630                                 int srcX, int srcY,
631                                 int maskX, int maskY,
632                                 int dstX, int dstY,
633                                 int w, int h);
634 #define R128CCEDoneComposite R128Done
635 #endif
636 #endif
637 
638 
639 #define CCE_PACKET0( reg, n )						\
640 	(R128_CCE_PACKET0 | ((n) << 16) | ((reg) >> 2))
641 #define CCE_PACKET1( reg0, reg1 )					\
642 	(R128_CCE_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
643 #define CCE_PACKET2()							\
644 	(R128_CCE_PACKET2)
645 #define CCE_PACKET3( pkt, n )						\
646 	(R128_CCE_PACKET3 | (pkt) | ((n) << 16))
647 
648 
649 #define R128_VERBOSE	0
650 
651 #define RING_LOCALS	uint32_t *__head; int __count;
652 
653 #define R128CCE_REFRESH(pScrn, info)					\
654 do {									\
655    if ( R128_VERBOSE ) {						\
656       xf86DrvMsg( pScrn->scrnIndex, X_INFO, "REFRESH( %d ) in %s\n",	\
657 		  !info->CCEInUse , __FUNCTION__ );			\
658    }									\
659    if ( !info->CCEInUse ) {						\
660       R128CCEWaitForIdle(pScrn);					\
661       BEGIN_RING( 6 );							\
662       OUT_RING_REG( R128_RE_TOP_LEFT,     info->re_top_left );		\
663       OUT_RING_REG( R128_RE_WIDTH_HEIGHT, info->re_width_height );	\
664       OUT_RING_REG( R128_AUX_SC_CNTL,     info->aux_sc_cntl );		\
665       ADVANCE_RING();							\
666       info->CCEInUse = TRUE;						\
667    }									\
668 } while (0)
669 
670 #define BEGIN_RING( n ) do {						\
671    if ( R128_VERBOSE ) {						\
672       xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
673 		  "BEGIN_RING( %d ) in %s\n", n, __FUNCTION__ );	\
674    }									\
675    if ( !info->indirectBuffer ) {					\
676       info->indirectBuffer = R128CCEGetBuffer( pScrn );			\
677       info->indirectStart = 0;						\
678    } else if ( (info->indirectBuffer->used + 4*(n)) >			\
679                 info->indirectBuffer->total ) {				\
680       R128CCEFlushIndirect( pScrn, 1 );					\
681    }									\
682    __head = (pointer)((char *)info->indirectBuffer->address +		\
683 		       info->indirectBuffer->used);			\
684    __count = 0;								\
685 } while (0)
686 
687 #define ADVANCE_RING() do {						\
688    if ( R128_VERBOSE ) {						\
689       xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
690 		  "ADVANCE_RING() used: %d+%d=%d/%d\n",			\
691 		  info->indirectBuffer->used - info->indirectStart,	\
692 		  __count * (int)sizeof(uint32_t),			\
693 		  info->indirectBuffer->used - info->indirectStart +	\
694 		  __count * (int)sizeof(uint32_t),			\
695 		  info->indirectBuffer->total - info->indirectStart );	\
696    }									\
697    info->indirectBuffer->used += __count * (int)sizeof(uint32_t);		\
698 } while (0)
699 
700 #define OUT_RING( x ) do {						\
701    if ( R128_VERBOSE ) {						\
702       xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
703 		  "   OUT_RING( 0x%08x )\n", (unsigned int)(x) );	\
704    }									\
705    MMIO_OUT32(&__head[__count++], 0, (x));				\
706 } while (0)
707 
708 #define OUT_RING_REG( reg, val )					\
709 do {									\
710    OUT_RING( CCE_PACKET0( reg, 0 ) );					\
711    OUT_RING( val );							\
712 } while (0)
713 
714 #define FLUSH_RING()							\
715 do {									\
716    if ( R128_VERBOSE )							\
717       xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
718 		  "FLUSH_RING in %s\n", __FUNCTION__ );			\
719    if ( info->indirectBuffer ) {					\
720       R128CCEFlushIndirect( pScrn, 0 );					\
721    }									\
722 } while (0)
723 
724 #endif
725