r128.h revision 79e5230e
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				/* XAA and Cursor Support */
47#include "xaa.h"
48#include "xf86Cursor.h"
49
50				/* DDC support */
51#include "xf86DDC.h"
52
53				/* Xv support */
54#include "xf86xv.h"
55
56#include "r128_probe.h"
57
58				/* DRI support */
59#ifdef XF86DRI
60#define _XF86DRI_SERVER_
61#include "r128_dripriv.h"
62#include "dri.h"
63#include "GL/glxint.h"
64#endif
65
66#include "atipcirename.h"
67
68#define R128_DEBUG          0   /* Turn off debugging output               */
69#define R128_IDLE_RETRY    32   /* Fall out of idle loops after this count */
70#define R128_TIMEOUT  2000000   /* Fall out of wait loops after this count */
71#define R128_MMIOSIZE  0x4000
72
73#define R128_VBIOS_SIZE 0x00010000
74
75#if R128_DEBUG
76#define R128TRACE(x)                                          \
77    do {                                                      \
78	ErrorF("(**) %s(%d): ", R128_NAME, pScrn->scrnIndex); \
79	ErrorF x;                                             \
80    } while (0);
81#else
82#define R128TRACE(x)
83#endif
84
85
86/* Other macros */
87#define R128_ARRAY_SIZE(x)  (sizeof(x)/sizeof(x[0]))
88#define R128_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
89#define R128PTR(pScrn) ((R128InfoPtr)(pScrn)->driverPrivate)
90
91typedef struct {        /* All values in XCLKS    */
92    int  ML;            /* Memory Read Latency    */
93    int  MB;            /* Memory Burst Length    */
94    int  Trcd;          /* RAS to CAS delay       */
95    int  Trp;           /* RAS percentage         */
96    int  Twr;           /* Write Recovery         */
97    int  CL;            /* CAS Latency            */
98    int  Tr2w;          /* Read to Write Delay    */
99    int  Rloop;         /* Loop Latency           */
100    int  Rloop_fudge;   /* Add to ML to get Rloop */
101    char *name;
102} R128RAMRec, *R128RAMPtr;
103
104typedef struct {
105				/* Common registers */
106    CARD32     ovr_clr;
107    CARD32     ovr_wid_left_right;
108    CARD32     ovr_wid_top_bottom;
109    CARD32     ov0_scale_cntl;
110    CARD32     mpp_tb_config;
111    CARD32     mpp_gp_config;
112    CARD32     subpic_cntl;
113    CARD32     viph_control;
114    CARD32     i2c_cntl_1;
115    CARD32     gen_int_cntl;
116    CARD32     cap0_trig_cntl;
117    CARD32     cap1_trig_cntl;
118    CARD32     bus_cntl;
119    CARD32     config_cntl;
120
121				/* Other registers to save for VT switches */
122    CARD32     dp_datatype;
123    CARD32     gen_reset_cntl;
124    CARD32     clock_cntl_index;
125    CARD32     amcgpio_en_reg;
126    CARD32     amcgpio_mask;
127
128				/* CRTC registers */
129    CARD32     crtc_gen_cntl;
130    CARD32     crtc_ext_cntl;
131    CARD32     dac_cntl;
132    CARD32     crtc_h_total_disp;
133    CARD32     crtc_h_sync_strt_wid;
134    CARD32     crtc_v_total_disp;
135    CARD32     crtc_v_sync_strt_wid;
136    CARD32     crtc_offset;
137    CARD32     crtc_offset_cntl;
138    CARD32     crtc_pitch;
139
140				/* CRTC2 registers */
141    CARD32     crtc2_gen_cntl;
142    CARD32     crtc2_h_total_disp;
143    CARD32     crtc2_h_sync_strt_wid;
144    CARD32     crtc2_v_total_disp;
145    CARD32     crtc2_v_sync_strt_wid;
146    CARD32     crtc2_offset;
147    CARD32     crtc2_offset_cntl;
148    CARD32     crtc2_pitch;
149
150				/* Flat panel registers */
151    CARD32     fp_crtc_h_total_disp;
152    CARD32     fp_crtc_v_total_disp;
153    CARD32     fp_gen_cntl;
154    CARD32     fp_h_sync_strt_wid;
155    CARD32     fp_horz_stretch;
156    CARD32     fp_panel_cntl;
157    CARD32     fp_v_sync_strt_wid;
158    CARD32     fp_vert_stretch;
159    CARD32     lvds_gen_cntl;
160    CARD32     tmds_crc;
161    CARD32     tmds_transmitter_cntl;
162
163				/* Computed values for PLL */
164    CARD32     dot_clock_freq;
165    CARD32     pll_output_freq;
166    int        feedback_div;
167    int        post_div;
168
169				/* PLL registers */
170    CARD32     ppll_ref_div;
171    CARD32     ppll_div_3;
172    CARD32     htotal_cntl;
173
174				/* Computed values for PLL2 */
175    CARD32     dot_clock_freq_2;
176    CARD32     pll_output_freq_2;
177    int        feedback_div_2;
178    int        post_div_2;
179
180				/* PLL2 registers */
181    CARD32     p2pll_ref_div;
182    CARD32     p2pll_div_0;
183    CARD32     htotal_cntl2;
184
185				/* DDA register */
186    CARD32     dda_config;
187    CARD32     dda_on_off;
188
189				/* DDA2 register */
190    CARD32     dda2_config;
191    CARD32     dda2_on_off;
192
193				/* Pallet */
194    Bool       palette_valid;
195    CARD32     palette[256];
196    CARD32     palette2[256];
197} R128SaveRec, *R128SavePtr;
198
199typedef struct {
200    CARD16        reference_freq;
201    CARD16        reference_div;
202    unsigned      min_pll_freq;
203    unsigned      max_pll_freq;
204    CARD16        xclk;
205} R128PLLRec, *R128PLLPtr;
206
207typedef struct {
208    int                bitsPerPixel;
209    int                depth;
210    int                displayWidth;
211    int                pixel_code;
212    int                pixel_bytes;
213    DisplayModePtr     mode;
214} R128FBLayout;
215
216typedef enum
217{
218    MT_NONE,
219    MT_CRT,
220    MT_LCD,
221    MT_DFP,
222    MT_CTV,
223    MT_STV
224} R128MonitorType;
225
226typedef struct {
227    EntityInfoPtr     pEnt;
228    pciVideoPtr       PciInfo;
229    PCITAG            PciTag;
230    int               Chipset;
231    Bool              Primary;
232
233#ifndef AVOID_FBDEV
234    Bool              FBDev;
235#endif
236
237    unsigned long     LinearAddr;   /* Frame buffer physical address         */
238    unsigned long     MMIOAddr;     /* MMIO region physical address          */
239    unsigned long     BIOSAddr;     /* BIOS physical address                 */
240
241    void              *MMIO;        /* Map of MMIO region                    */
242    void              *FB;          /* Map of frame buffer                   */
243
244    CARD32            MemCntl;
245    CARD32            BusCntl;
246    unsigned long     FbMapSize;    /* Size of frame buffer, in bytes        */
247    int               Flags;        /* Saved copy of mode flags              */
248
249    CARD8             BIOSDisplay;  /* Device the BIOS is set to display to  */
250
251    Bool              HasPanelRegs; /* Current chip can connect to a FP      */
252    CARD8             *VBIOS;       /* Video BIOS for mode validation on FPs */
253    int               FPBIOSstart;  /* Start of the flat panel info          */
254
255				/* Computed values for FPs */
256    int               PanelXRes;
257    int               PanelYRes;
258    int               HOverPlus;
259    int               HSyncWidth;
260    int               HBlank;
261    int               VOverPlus;
262    int               VSyncWidth;
263    int               VBlank;
264    int               PanelPwrDly;
265
266    R128PLLRec        pll;
267    R128RAMPtr        ram;
268
269    R128SaveRec       SavedReg;     /* Original (text) mode                  */
270    R128SaveRec       ModeReg;      /* Current mode                          */
271    Bool              (*CloseScreen)(int, ScreenPtr);
272    void              (*BlockHandler)(int, pointer, pointer, pointer);
273
274    Bool              PaletteSavedOnVT; /* Palette saved on last VT switch   */
275
276    XAAInfoRecPtr     accel;
277    Bool              accelOn;
278    xf86CursorInfoPtr cursor;
279    unsigned long     cursor_start;
280    unsigned long     cursor_end;
281
282    /*
283     * XAAForceTransBlit is used to change the behavior of the XAA
284     * SetupForScreenToScreenCopy function, to make it DGA-friendly.
285     */
286    Bool              XAAForceTransBlit;
287
288    int               fifo_slots;   /* Free slots in the FIFO (64 max)       */
289    int               pix24bpp;     /* Depth of pixmap for 24bpp framebuffer */
290    Bool              dac6bits;     /* Use 6 bit DAC?                        */
291
292				/* Computed values for Rage 128 */
293    int               pitch;
294    int               datatype;
295    CARD32            dp_gui_master_cntl;
296
297				/* Saved values for ScreenToScreenCopy */
298    int               xdir;
299    int               ydir;
300
301				/* ScanlineScreenToScreenColorExpand support */
302    unsigned char     *scratch_buffer[1];
303    unsigned char     *scratch_save;
304    int               scanline_x;
305    int               scanline_y;
306    int               scanline_w;
307    int               scanline_h;
308#ifdef XF86DRI
309    int               scanline_hpass;
310    int               scanline_x1clip;
311    int               scanline_x2clip;
312    int               scanline_rop;
313    int               scanline_fg;
314    int               scanline_bg;
315#endif /* XF86DRI */
316    int               scanline_words;
317    int               scanline_direct;
318    int               scanline_bpp; /* Only used for ImageWrite */
319
320    DGAModePtr        DGAModes;
321    int               numDGAModes;
322    Bool              DGAactive;
323    int               DGAViewportStatus;
324    DGAFunctionRec    DGAFuncs;
325
326    R128FBLayout      CurrentLayout;
327#ifdef XF86DRI
328    Bool              directRenderingEnabled;
329    DRIInfoPtr        pDRIInfo;
330    int               drmFD;
331    drm_context_t        drmCtx;
332    int               numVisualConfigs;
333    __GLXvisualConfig *pVisualConfigs;
334    R128ConfigPrivPtr pVisualConfigsPriv;
335
336    drm_handle_t         fbHandle;
337
338    drmSize           registerSize;
339    drm_handle_t         registerHandle;
340
341    Bool              IsPCI;            /* Current card is a PCI card */
342    drmSize           pciSize;
343    drm_handle_t         pciMemHandle;
344    drmAddress        PCI;              /* Map */
345
346    Bool              allowPageFlip;    /* Enable 3d page flipping */
347    Bool              have3DWindows;    /* Are there any 3d clients? */
348    int               drmMinor;
349
350    drmSize           agpSize;
351    drm_handle_t         agpMemHandle;     /* Handle from drmAgpAlloc */
352    unsigned long     agpOffset;
353    drmAddress        AGP;              /* Map */
354    int               agpMode;
355
356    Bool              CCEInUse;         /* CCE is currently active */
357    int               CCEMode;          /* CCE mode that server/clients use */
358    int               CCEFifoSize;      /* Size of the CCE command FIFO */
359    Bool              CCESecure;        /* CCE security enabled */
360    int               CCEusecTimeout;   /* CCE timeout in usecs */
361
362				/* CCE ring buffer data */
363    unsigned long     ringStart;        /* Offset into AGP space */
364    drm_handle_t         ringHandle;       /* Handle from drmAddMap */
365    drmSize           ringMapSize;      /* Size of map */
366    int               ringSize;         /* Size of ring (in MB) */
367    drmAddress        ring;             /* Map */
368    int               ringSizeLog2QW;
369
370    unsigned long     ringReadOffset;   /* Offset into AGP space */
371    drm_handle_t         ringReadPtrHandle; /* Handle from drmAddMap */
372    drmSize           ringReadMapSize;  /* Size of map */
373    drmAddress        ringReadPtr;      /* Map */
374
375				/* CCE vertex/indirect buffer data */
376    unsigned long     bufStart;        /* Offset into AGP space */
377    drm_handle_t         bufHandle;       /* Handle from drmAddMap */
378    drmSize           bufMapSize;      /* Size of map */
379    int               bufSize;         /* Size of buffers (in MB) */
380    drmAddress        buf;             /* Map */
381    int               bufNumBufs;      /* Number of buffers */
382    drmBufMapPtr      buffers;         /* Buffer map */
383
384				/* CCE AGP Texture data */
385    unsigned long     agpTexStart;      /* Offset into AGP space */
386    drm_handle_t         agpTexHandle;     /* Handle from drmAddMap */
387    drmSize           agpTexMapSize;    /* Size of map */
388    int               agpTexSize;       /* Size of AGP tex space (in MB) */
389    drmAddress        agpTex;           /* Map */
390    int               log2AGPTexGran;
391
392				/* CCE 2D accleration */
393    drmBufPtr         indirectBuffer;
394    int               indirectStart;
395
396				/* DRI screen private data */
397    int               fbX;
398    int               fbY;
399    int               backX;
400    int               backY;
401    int               depthX;
402    int               depthY;
403
404    int               frontOffset;
405    int               frontPitch;
406    int               backOffset;
407    int               backPitch;
408    int               depthOffset;
409    int               depthPitch;
410    int               spanOffset;
411    int               textureOffset;
412    int               textureSize;
413    int               log2TexGran;
414
415				/* Saved scissor values */
416    CARD32            sc_left;
417    CARD32            sc_right;
418    CARD32            sc_top;
419    CARD32            sc_bottom;
420
421    CARD32            re_top_left;
422    CARD32            re_width_height;
423
424    CARD32            aux_sc_cntl;
425
426    int               irq;
427    CARD32            gen_int_cntl;
428
429    Bool              DMAForXv;
430#endif
431
432    XF86VideoAdaptorPtr adaptor;
433    void              (*VideoTimerCallback)(ScrnInfoPtr, Time);
434    int               videoKey;
435    Bool              showCache;
436    OptionInfoPtr     Options;
437
438    Bool              isDFP;
439    Bool              isPro2;
440    I2CBusPtr         pI2CBus;
441    CARD32            DDCReg;
442
443    Bool              VGAAccess;
444
445    /****** Added for dualhead support *******************/
446    BOOL              HasCRTC2;     /* M3/M4 */
447    BOOL              IsSecondary;  /* second Screen */
448    BOOL	      IsPrimary;    /* primary Screen */
449    BOOL              UseCRT;       /* force use CRT port as primary */
450    BOOL              SwitchingMode;
451    R128MonitorType DisplayType;  /* Monitor connected on*/
452
453} R128InfoRec, *R128InfoPtr;
454
455#define R128WaitForFifo(pScrn, entries)                                      \
456do {                                                                         \
457    if (info->fifo_slots < entries) R128WaitForFifoFunction(pScrn, entries); \
458    info->fifo_slots -= entries;                                             \
459} while (0)
460
461extern R128EntPtr R128EntPriv(ScrnInfoPtr pScrn);
462extern void        R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries);
463extern void        R128WaitForIdle(ScrnInfoPtr pScrn);
464extern void        R128EngineReset(ScrnInfoPtr pScrn);
465extern void        R128EngineFlush(ScrnInfoPtr pScrn);
466
467extern unsigned    R128INPLL(ScrnInfoPtr pScrn, int addr);
468extern void        R128WaitForVerticalSync(ScrnInfoPtr pScrn);
469
470extern Bool        R128AccelInit(ScreenPtr pScreen);
471extern void        R128EngineInit(ScrnInfoPtr pScrn);
472extern Bool        R128CursorInit(ScreenPtr pScreen);
473extern Bool        R128DGAInit(ScreenPtr pScreen);
474
475extern int         R128MinBits(int val);
476
477extern void        R128InitVideo(ScreenPtr pScreen);
478
479#ifdef XF86DRI
480extern Bool        R128DRIScreenInit(ScreenPtr pScreen);
481extern void        R128DRICloseScreen(ScreenPtr pScreen);
482extern Bool        R128DRIFinishScreenInit(ScreenPtr pScreen);
483
484#define R128CCE_START(pScrn, info)					\
485do {									\
486    int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_START);		\
487    if (_ret) {								\
488	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,				\
489		   "%s: CCE start %d\n", __FUNCTION__, _ret);		\
490    }									\
491} while (0)
492
493#define R128CCE_STOP(pScrn, info)					\
494do {									\
495    int _ret = R128CCEStop(pScrn);					\
496    if (_ret) {								\
497	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,				\
498		   "%s: CCE stop %d\n", __FUNCTION__, _ret);		\
499    }									\
500} while (0)
501
502#define R128CCE_RESET(pScrn, info)					\
503do {									\
504    if (info->directRenderingEnabled					\
505	&& R128CCE_USE_RING_BUFFER(info->CCEMode)) {			\
506	int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_RESET);	\
507	if (_ret) {							\
508	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,			\
509		       "%s: CCE reset %d\n", __FUNCTION__, _ret);	\
510	}								\
511    }									\
512} while (0)
513
514extern drmBufPtr   R128CCEGetBuffer(ScrnInfoPtr pScrn);
515#endif
516
517extern void        R128CCEFlushIndirect(ScrnInfoPtr pScrn, int discard);
518extern void        R128CCEReleaseIndirect(ScrnInfoPtr pScrn);
519extern void        R128CCEWaitForIdle(ScrnInfoPtr pScrn);
520extern int         R128CCEStop(ScrnInfoPtr pScrn);
521
522
523#define CCE_PACKET0( reg, n )						\
524	(R128_CCE_PACKET0 | ((n) << 16) | ((reg) >> 2))
525#define CCE_PACKET1( reg0, reg1 )					\
526	(R128_CCE_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
527#define CCE_PACKET2()							\
528	(R128_CCE_PACKET2)
529#define CCE_PACKET3( pkt, n )						\
530	(R128_CCE_PACKET3 | (pkt) | ((n) << 16))
531
532
533#define R128_VERBOSE	0
534
535#define RING_LOCALS	CARD32 *__head; int __count;
536
537#define R128CCE_REFRESH(pScrn, info)					\
538do {									\
539   if ( R128_VERBOSE ) {						\
540      xf86DrvMsg( pScrn->scrnIndex, X_INFO, "REFRESH( %d ) in %s\n",	\
541		  !info->CCEInUse , __FUNCTION__ );			\
542   }									\
543   if ( !info->CCEInUse ) {						\
544      R128CCEWaitForIdle(pScrn);					\
545      BEGIN_RING( 6 );							\
546      OUT_RING_REG( R128_RE_TOP_LEFT,     info->re_top_left );		\
547      OUT_RING_REG( R128_RE_WIDTH_HEIGHT, info->re_width_height );	\
548      OUT_RING_REG( R128_AUX_SC_CNTL,     info->aux_sc_cntl );		\
549      ADVANCE_RING();							\
550      info->CCEInUse = TRUE;						\
551   }									\
552} while (0)
553
554#define BEGIN_RING( n ) do {						\
555   if ( R128_VERBOSE ) {						\
556      xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
557		  "BEGIN_RING( %d ) in %s\n", n, __FUNCTION__ );	\
558   }									\
559   if ( !info->indirectBuffer ) {					\
560      info->indirectBuffer = R128CCEGetBuffer( pScrn );			\
561      info->indirectStart = 0;						\
562   } else if ( (info->indirectBuffer->used + 4*(n)) >			\
563                info->indirectBuffer->total ) {				\
564      R128CCEFlushIndirect( pScrn, 1 );					\
565   }									\
566   __head = (pointer)((char *)info->indirectBuffer->address +		\
567		       info->indirectBuffer->used);			\
568   __count = 0;								\
569} while (0)
570
571#define ADVANCE_RING() do {						\
572   if ( R128_VERBOSE ) {						\
573      xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
574		  "ADVANCE_RING() used: %d+%d=%d/%d\n",			\
575		  info->indirectBuffer->used - info->indirectStart,	\
576		  __count * (int)sizeof(CARD32),			\
577		  info->indirectBuffer->used - info->indirectStart +	\
578		  __count * (int)sizeof(CARD32),			\
579		  info->indirectBuffer->total - info->indirectStart );	\
580   }									\
581   info->indirectBuffer->used += __count * (int)sizeof(CARD32);		\
582} while (0)
583
584#define OUT_RING( x ) do {						\
585   if ( R128_VERBOSE ) {						\
586      xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
587		  "   OUT_RING( 0x%08x )\n", (unsigned int)(x) );	\
588   }									\
589   MMIO_OUT32(&__head[__count++], 0, (x));				\
590} while (0)
591
592#define OUT_RING_REG( reg, val )					\
593do {									\
594   OUT_RING( CCE_PACKET0( reg, 0 ) );					\
595   OUT_RING( val );							\
596} while (0)
597
598#define FLUSH_RING()							\
599do {									\
600   if ( R128_VERBOSE )							\
601      xf86DrvMsg( pScrn->scrnIndex, X_INFO,				\
602		  "FLUSH_RING in %s\n", __FUNCTION__ );			\
603   if ( info->indirectBuffer ) {					\
604      R128CCEFlushIndirect( pScrn, 0 );					\
605   }									\
606} while (0)
607
608#endif
609