r128.h revision a0e1ef58
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#include "GL/glxint.h"
74#endif
75
76#include "fb.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#define R128_NAME "R128"
120
121#if R128_DEBUG
122#include "r128_version.h"
123
124#define R128TRACE(x)                                          \
125    do {                                                      \
126	ErrorF("(**) %s(%d): ", R128_NAME, pScrn->scrnIndex); \
127	ErrorF x;                                             \
128    } while (0);
129#else
130#define R128TRACE(x)
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
139typedef struct {        /* All values in XCLKS    */
140    int  ML;            /* Memory Read Latency    */
141    int  MB;            /* Memory Burst Length    */
142    int  Trcd;          /* RAS to CAS delay       */
143    int  Trp;           /* RAS percentage         */
144    int  Twr;           /* Write Recovery         */
145    int  CL;            /* CAS Latency            */
146    int  Tr2w;          /* Read to Write Delay    */
147    int  Rloop;         /* Loop Latency           */
148    int  Rloop_fudge;   /* Add to ML to get Rloop */
149    char *name;
150} R128RAMRec, *R128RAMPtr;
151
152typedef struct {
153				/* Common registers */
154    CARD32     ovr_clr;
155    CARD32     ovr_wid_left_right;
156    CARD32     ovr_wid_top_bottom;
157    CARD32     ov0_scale_cntl;
158    CARD32     mpp_tb_config;
159    CARD32     mpp_gp_config;
160    CARD32     subpic_cntl;
161    CARD32     viph_control;
162    CARD32     i2c_cntl_1;
163    CARD32     gen_int_cntl;
164    CARD32     cap0_trig_cntl;
165    CARD32     cap1_trig_cntl;
166    CARD32     bus_cntl;
167    CARD32     config_cntl;
168
169				/* Other registers to save for VT switches */
170    CARD32     dp_datatype;
171    CARD32     gen_reset_cntl;
172    CARD32     clock_cntl_index;
173    CARD32     amcgpio_en_reg;
174    CARD32     amcgpio_mask;
175
176				/* CRTC registers */
177    CARD32     crtc_gen_cntl;
178    CARD32     crtc_ext_cntl;
179    CARD32     dac_cntl;
180    CARD32     crtc_h_total_disp;
181    CARD32     crtc_h_sync_strt_wid;
182    CARD32     crtc_v_total_disp;
183    CARD32     crtc_v_sync_strt_wid;
184    CARD32     crtc_offset;
185    CARD32     crtc_offset_cntl;
186    CARD32     crtc_pitch;
187
188				/* CRTC2 registers */
189    CARD32     crtc2_gen_cntl;
190    CARD32     crtc2_h_total_disp;
191    CARD32     crtc2_h_sync_strt_wid;
192    CARD32     crtc2_v_total_disp;
193    CARD32     crtc2_v_sync_strt_wid;
194    CARD32     crtc2_offset;
195    CARD32     crtc2_offset_cntl;
196    CARD32     crtc2_pitch;
197
198				/* Flat panel registers */
199    CARD32     fp_crtc_h_total_disp;
200    CARD32     fp_crtc_v_total_disp;
201    CARD32     fp_gen_cntl;
202    CARD32     fp_h_sync_strt_wid;
203    CARD32     fp_horz_stretch;
204    CARD32     fp_panel_cntl;
205    CARD32     fp_v_sync_strt_wid;
206    CARD32     fp_vert_stretch;
207    CARD32     lvds_gen_cntl;
208    CARD32     tmds_crc;
209    CARD32     tmds_transmitter_cntl;
210
211				/* Computed values for PLL */
212    CARD32     dot_clock_freq;
213    CARD32     pll_output_freq;
214    int        feedback_div;
215    int        post_div;
216
217				/* PLL registers */
218    CARD32     ppll_ref_div;
219    CARD32     ppll_div_3;
220    CARD32     ppll_div_0;
221    CARD32     htotal_cntl;
222
223				/* Computed values for PLL2 */
224    CARD32     dot_clock_freq_2;
225    CARD32     pll_output_freq_2;
226    int        feedback_div_2;
227    int        post_div_2;
228
229				/* PLL2 registers */
230    CARD32     p2pll_ref_div;
231    CARD32     p2pll_div_0;
232    CARD32     htotal_cntl2;
233
234				/* DDA register */
235    CARD32     dda_config;
236    CARD32     dda_on_off;
237
238				/* DDA2 register */
239    CARD32     dda2_config;
240    CARD32     dda2_on_off;
241
242				/* Pallet */
243    Bool       palette_valid;
244    CARD32     palette[256];
245    CARD32     palette2[256];
246} R128SaveRec, *R128SavePtr;
247
248typedef struct {
249    CARD16        reference_freq;
250    CARD16        reference_div;
251    unsigned      min_pll_freq;
252    unsigned      max_pll_freq;
253    CARD16        xclk;
254} R128PLLRec, *R128PLLPtr;
255
256typedef struct {
257    int                bitsPerPixel;
258    int                depth;
259    int                displayWidth;
260    int                pixel_code;
261    int                pixel_bytes;
262    DisplayModePtr     mode;
263} R128FBLayout;
264
265typedef enum
266{
267    MT_NONE,
268    MT_CRT,
269    MT_LCD,
270    MT_DFP,
271    MT_CTV,
272    MT_STV
273} R128MonitorType;
274
275#ifdef USE_EXA
276struct r128_2d_state {
277    Bool in_use;
278    Bool composite_setup;
279    uint32_t dst_pitch_offset;
280    uint32_t src_pitch_offset;
281    uint32_t dp_gui_master_cntl;
282    uint32_t dp_cntl;
283    uint32_t dp_write_mask;
284    uint32_t dp_brush_frgd_clr;
285    uint32_t dp_brush_bkgd_clr;
286    uint32_t dp_src_frgd_clr;
287    uint32_t dp_src_bkgd_clr;
288    uint32_t default_sc_bottom_right;
289#if defined(R128DRI) && defined(RENDER)
290    Bool has_mask;
291    int x_offset;
292    int y_offset;
293    int widths[2];
294    int heights[2];
295    Bool is_transform[2];
296    PictTransform *transform[2];
297    PixmapPtr src_pix;
298    PixmapPtr msk_pix;
299#endif
300};
301#endif
302
303typedef struct {
304    EntityInfoPtr     pEnt;
305    pciVideoPtr       PciInfo;
306    PCITAG            PciTag;
307    int               Chipset;
308    Bool              Primary;
309
310#ifndef AVOID_FBDEV
311    Bool              FBDev;
312#endif
313
314    unsigned long     LinearAddr;   /* Frame buffer physical address         */
315    unsigned long     MMIOAddr;     /* MMIO region physical address          */
316    unsigned long     BIOSAddr;     /* BIOS physical address                 */
317
318    void              *MMIO;        /* Map of MMIO region                    */
319    void              *FB;          /* Map of frame buffer                   */
320
321    CARD32            MemCntl;
322    CARD32            BusCntl;
323    unsigned long     FbMapSize;    /* Size of frame buffer, in bytes        */
324    int               Flags;        /* Saved copy of mode flags              */
325
326    CARD8             BIOSDisplay;  /* Device the BIOS is set to display to  */
327
328    Bool              HasPanelRegs; /* Current chip can connect to a FP      */
329    CARD8             *VBIOS;       /* Video BIOS for mode validation on FPs */
330    int               FPBIOSstart;  /* Start of the flat panel info          */
331
332				/* Computed values for FPs */
333    int               PanelXRes;
334    int               PanelYRes;
335    int               HOverPlus;
336    int               HSyncWidth;
337    int               HBlank;
338    int               VOverPlus;
339    int               VSyncWidth;
340    int               VBlank;
341    int               PanelPwrDly;
342
343    R128PLLRec        pll;
344    R128RAMPtr        ram;
345
346    R128SaveRec       SavedReg;     /* Original (text) mode                  */
347    R128SaveRec       ModeReg;      /* Current mode                          */
348    Bool              (*CloseScreen)(CLOSE_SCREEN_ARGS_DECL);
349    void              (*BlockHandler)(BLOCKHANDLER_ARGS_DECL);
350
351    Bool              PaletteSavedOnVT; /* Palette saved on last VT switch   */
352
353#ifdef HAVE_XAA_H
354    XAAInfoRecPtr     accel;
355#endif
356    Bool              accelOn;
357
358    Bool	      useEXA;
359    Bool	      RenderAccel;
360#ifdef USE_EXA
361    ExaDriverPtr      ExaDriver;
362    XF86ModReqInfo    exaReq;
363    struct r128_2d_state state_2d;
364#endif
365
366    xf86CursorInfoPtr cursor;
367    unsigned long     cursor_start;
368    unsigned long     cursor_end;
369
370    /*
371     * XAAForceTransBlit is used to change the behavior of the XAA
372     * SetupForScreenToScreenCopy function, to make it DGA-friendly.
373     */
374    Bool              XAAForceTransBlit;
375
376    int               fifo_slots;   /* Free slots in the FIFO (64 max)       */
377    int               pix24bpp;     /* Depth of pixmap for 24bpp framebuffer */
378    Bool              dac6bits;     /* Use 6 bit DAC?                        */
379
380				/* Computed values for Rage 128 */
381    int               pitch;
382    int               datatype;
383    CARD32            dp_gui_master_cntl;
384
385				/* Saved values for ScreenToScreenCopy */
386    int               xdir;
387    int               ydir;
388
389				/* ScanlineScreenToScreenColorExpand support */
390    unsigned char     *scratch_buffer[1];
391    unsigned char     *scratch_save;
392    int               scanline_x;
393    int               scanline_y;
394    int               scanline_w;
395    int               scanline_h;
396#ifdef R128DRI
397    int               scanline_hpass;
398    int               scanline_x1clip;
399    int               scanline_x2clip;
400    int               scanline_rop;
401    int               scanline_fg;
402    int               scanline_bg;
403#endif /* R128DRI */
404    int               scanline_words;
405    int               scanline_direct;
406    int               scanline_bpp; /* Only used for ImageWrite */
407
408    DGAModePtr        DGAModes;
409    int               numDGAModes;
410    Bool              DGAactive;
411    int               DGAViewportStatus;
412    DGAFunctionRec    DGAFuncs;
413
414    R128FBLayout      CurrentLayout;
415#ifdef R128DRI
416    Bool              directRenderingEnabled;
417    DRIInfoPtr        pDRIInfo;
418    int               drmFD;
419    drm_context_t        drmCtx;
420    int               numVisualConfigs;
421    __GLXvisualConfig *pVisualConfigs;
422    R128ConfigPrivPtr pVisualConfigsPriv;
423
424    drm_handle_t         fbHandle;
425
426    drmSize           registerSize;
427    drm_handle_t         registerHandle;
428
429    Bool              IsPCI;            /* Current card is a PCI card */
430    drmSize           pciSize;
431    drm_handle_t         pciMemHandle;
432    drmAddress        PCI;              /* Map */
433
434    Bool              allowPageFlip;    /* Enable 3d page flipping */
435    Bool              have3DWindows;    /* Are there any 3d clients? */
436    int               drmMinor;
437
438    drmSize           agpSize;
439    drm_handle_t         agpMemHandle;     /* Handle from drmAgpAlloc */
440    unsigned long     agpOffset;
441    drmAddress        AGP;              /* Map */
442    int               agpMode;
443
444    Bool              CCEInUse;         /* CCE is currently active */
445    int               CCEMode;          /* CCE mode that server/clients use */
446    int               CCEFifoSize;      /* Size of the CCE command FIFO */
447    Bool              CCESecure;        /* CCE security enabled */
448    int               CCEusecTimeout;   /* CCE timeout in usecs */
449
450				/* CCE ring buffer data */
451    unsigned long     ringStart;        /* Offset into AGP space */
452    drm_handle_t         ringHandle;       /* Handle from drmAddMap */
453    drmSize           ringMapSize;      /* Size of map */
454    int               ringSize;         /* Size of ring (in MB) */
455    drmAddress        ring;             /* Map */
456    int               ringSizeLog2QW;
457
458    unsigned long     ringReadOffset;   /* Offset into AGP space */
459    drm_handle_t         ringReadPtrHandle; /* Handle from drmAddMap */
460    drmSize           ringReadMapSize;  /* Size of map */
461    drmAddress        ringReadPtr;      /* Map */
462
463				/* CCE vertex/indirect buffer data */
464    unsigned long     bufStart;        /* Offset into AGP space */
465    drm_handle_t         bufHandle;       /* Handle from drmAddMap */
466    drmSize           bufMapSize;      /* Size of map */
467    int               bufSize;         /* Size of buffers (in MB) */
468    drmAddress        buf;             /* Map */
469    int               bufNumBufs;      /* Number of buffers */
470    drmBufMapPtr      buffers;         /* Buffer map */
471
472				/* CCE AGP Texture data */
473    unsigned long     agpTexStart;      /* Offset into AGP space */
474    drm_handle_t         agpTexHandle;     /* Handle from drmAddMap */
475    drmSize           agpTexMapSize;    /* Size of map */
476    int               agpTexSize;       /* Size of AGP tex space (in MB) */
477    drmAddress        agpTex;           /* Map */
478    int               log2AGPTexGran;
479
480				/* CCE 2D accleration */
481    drmBufPtr         indirectBuffer;
482    int               indirectStart;
483
484				/* DRI screen private data */
485    int               fbX;
486    int               fbY;
487    int               backX;
488    int               backY;
489    int               depthX;
490    int               depthY;
491
492    int               frontOffset;
493    int               frontPitch;
494    int               backOffset;
495    int               backPitch;
496    int               depthOffset;
497    int               depthPitch;
498    int               spanOffset;
499    int               textureOffset;
500    int               textureSize;
501    int               log2TexGran;
502
503				/* Saved scissor values */
504    CARD32            sc_left;
505    CARD32            sc_right;
506    CARD32            sc_top;
507    CARD32            sc_bottom;
508
509    CARD32            re_top_left;
510    CARD32            re_width_height;
511
512    CARD32            aux_sc_cntl;
513
514    int               irq;
515    CARD32            gen_int_cntl;
516
517    Bool              DMAForXv;
518#endif
519
520    XF86VideoAdaptorPtr adaptor;
521    void              (*VideoTimerCallback)(ScrnInfoPtr, Time);
522    int               videoKey;
523    Bool              showCache;
524    OptionInfoPtr     Options;
525
526    Bool              isDFP;
527    Bool              isPro2;
528    I2CBusPtr         pI2CBus;
529    CARD32            DDCReg;
530
531    Bool              VGAAccess;
532
533    /****** Added for dualhead support *******************/
534    BOOL              HasCRTC2;     /* M3/M4 */
535    BOOL              IsSecondary;  /* second Screen */
536    BOOL	      IsPrimary;    /* primary Screen */
537    BOOL              UseCRT;       /* force use CRT port as primary */
538    BOOL              SwitchingMode;
539    R128MonitorType DisplayType;  /* Monitor connected on*/
540
541} R128InfoRec, *R128InfoPtr;
542
543#define R128WaitForFifo(pScrn, entries)                                      \
544do {                                                                         \
545    if (info->fifo_slots < entries) R128WaitForFifoFunction(pScrn, entries); \
546    info->fifo_slots -= entries;                                             \
547} while (0)
548
549extern R128EntPtr R128EntPriv(ScrnInfoPtr pScrn);
550extern void        R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries);
551extern void        R128WaitForIdle(ScrnInfoPtr pScrn);
552extern void        R128EngineReset(ScrnInfoPtr pScrn);
553extern void        R128EngineFlush(ScrnInfoPtr pScrn);
554
555extern unsigned    R128INPLL(ScrnInfoPtr pScrn, int addr);
556extern void        R128WaitForVerticalSync(ScrnInfoPtr pScrn);
557
558extern Bool        R128AccelInit(ScreenPtr pScreen);
559extern void        R128EngineInit(ScrnInfoPtr pScrn);
560extern Bool        R128CursorInit(ScreenPtr pScreen);
561extern Bool        R128DGAInit(ScreenPtr pScreen);
562
563extern int         R128MinBits(int val);
564
565extern void        R128InitVideo(ScreenPtr pScreen);
566
567#ifdef R128DRI
568extern Bool        R128DRIScreenInit(ScreenPtr pScreen);
569extern void        R128DRICloseScreen(ScreenPtr pScreen);
570extern Bool        R128DRIFinishScreenInit(ScreenPtr pScreen);
571
572#define R128CCE_START(pScrn, info)					\
573do {									\
574    int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_START);		\
575    if (_ret) {								\
576	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,				\
577		   "%s: CCE start %d\n", __FUNCTION__, _ret);		\
578    }									\
579} while (0)
580
581#define R128CCE_STOP(pScrn, info)					\
582do {									\
583    int _ret = R128CCEStop(pScrn);					\
584    if (_ret) {								\
585	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,				\
586		   "%s: CCE stop %d\n", __FUNCTION__, _ret);		\
587    }									\
588} while (0)
589
590#define R128CCE_RESET(pScrn, info)					\
591do {									\
592    if (info->directRenderingEnabled					\
593	&& R128CCE_USE_RING_BUFFER(info->CCEMode)) {			\
594	int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_RESET);	\
595	if (_ret) {							\
596	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,			\
597		       "%s: CCE reset %d\n", __FUNCTION__, _ret);	\
598	}								\
599    }									\
600} while (0)
601
602extern drmBufPtr   R128CCEGetBuffer(ScrnInfoPtr pScrn);
603#endif
604
605extern void        R128CCEFlushIndirect(ScrnInfoPtr pScrn, int discard);
606extern void        R128CCEReleaseIndirect(ScrnInfoPtr pScrn);
607extern void        R128CCEWaitForIdle(ScrnInfoPtr pScrn);
608extern int         R128CCEStop(ScrnInfoPtr pScrn);
609extern void	   R128CopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap);
610
611#ifdef USE_EXA
612extern Bool	   R128EXAInit(ScreenPtr pScreen);
613extern Bool	   R128GetDatatypeBpp(int bpp, uint32_t *type);
614extern Bool	   R128GetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset);
615extern void	   R128DoPrepareCopy(ScrnInfoPtr pScrn, uint32_t src_pitch_offset,
616				    uint32_t dst_pitch_offset, uint32_t datatype, int alu, Pixel planemask);
617#endif
618
619
620#define CCE_PACKET0( reg, n )						\
621	(R128_CCE_PACKET0 | ((n) << 16) | ((reg) >> 2))
622#define CCE_PACKET1( reg0, reg1 )					\
623	(R128_CCE_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
624#define CCE_PACKET2()							\
625	(R128_CCE_PACKET2)
626#define CCE_PACKET3( pkt, n )						\
627	(R128_CCE_PACKET3 | (pkt) | ((n) << 16))
628
629
630#define R128_VERBOSE	0
631
632#define RING_LOCALS	CARD32 *__head; int __count;
633
634#define R128CCE_REFRESH(pScrn, info)					\
635do {									\
636   if ( R128_VERBOSE ) {						\
637      xf86DrvMsg( pScrn->scrnIndex, X_INFO, "REFRESH( %d ) in %s\n",	\
638		  !info->CCEInUse , __FUNCTION__ );			\
639   }									\
640   if ( !info->CCEInUse ) {						\
641      R128CCEWaitForIdle(pScrn);					\
642      BEGIN_RING( 6 );							\
643      OUT_RING_REG( R128_RE_TOP_LEFT,     info->re_top_left );		\
644      OUT_RING_REG( R128_RE_WIDTH_HEIGHT, info->re_width_height );	\
645      OUT_RING_REG( R128_AUX_SC_CNTL,     info->aux_sc_cntl );		\
646      ADVANCE_RING();							\
647      info->CCEInUse = TRUE;						\
648   }									\
649} while (0)
650
651#define BEGIN_RING( n ) do {						\
652   if ( R128_VERBOSE ) {						\
653      xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
654		  "BEGIN_RING( %d ) in %s\n", n, __FUNCTION__ );	\
655   }									\
656   if ( !info->indirectBuffer ) {					\
657      info->indirectBuffer = R128CCEGetBuffer( pScrn );			\
658      info->indirectStart = 0;						\
659   } else if ( (info->indirectBuffer->used + 4*(n)) >			\
660                info->indirectBuffer->total ) {				\
661      R128CCEFlushIndirect( pScrn, 1 );					\
662   }									\
663   __head = (pointer)((char *)info->indirectBuffer->address +		\
664		       info->indirectBuffer->used);			\
665   __count = 0;								\
666} while (0)
667
668#define ADVANCE_RING() do {						\
669   if ( R128_VERBOSE ) {						\
670      xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
671		  "ADVANCE_RING() used: %d+%d=%d/%d\n",			\
672		  info->indirectBuffer->used - info->indirectStart,	\
673		  __count * (int)sizeof(CARD32),			\
674		  info->indirectBuffer->used - info->indirectStart +	\
675		  __count * (int)sizeof(CARD32),			\
676		  info->indirectBuffer->total - info->indirectStart );	\
677   }									\
678   info->indirectBuffer->used += __count * (int)sizeof(CARD32);		\
679} while (0)
680
681#define OUT_RING( x ) do {						\
682   if ( R128_VERBOSE ) {						\
683      xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
684		  "   OUT_RING( 0x%08x )\n", (unsigned int)(x) );	\
685   }									\
686   MMIO_OUT32(&__head[__count++], 0, (x));				\
687} while (0)
688
689#define OUT_RING_REG( reg, val )					\
690do {									\
691   OUT_RING( CCE_PACKET0( reg, 0 ) );					\
692   OUT_RING( val );							\
693} while (0)
694
695#define FLUSH_RING()							\
696do {									\
697   if ( R128_VERBOSE )							\
698      xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
699		  "FLUSH_RING in %s\n", __FUNCTION__ );			\
700   if ( info->indirectBuffer ) {					\
701      R128CCEFlushIndirect( pScrn, 0 );					\
702   }									\
703} while (0)
704
705#endif
706