1 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h,v 1.24 2002/12/16 16:19:10 dawes Exp $ */
3 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
4 * Precision Insight, Inc., Cedar Park, Texas, and
5 * VA Linux Systems Inc., Fremont, California.
9 * Permission is hereby granted, free of charge, to any person obtaining
10 * a copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation on the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of the Software,
14 * and to permit persons to whom the Software is furnished to do so,
15 * subject to the following conditions:
17 * The above copyright notice and this permission notice (including the
18 * next paragraph) shall be included in all copies or substantial
19 * portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, PRECISION INSIGHT, VA LINUX
25 * SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
33 * Rickard E. Faith <faith@valinux.com>
34 * Kevin E. Martin <martin@valinux.com>
48 /* XAA and Cursor Support */
50 #include "xf86Cursor.h"
60 #define _XF86DRI_SERVER_
61 #include "r128_dripriv.h"
63 #include "GL/glxint.h"
70 #define R128_DEBUG 0 /* Turn off debugging output */
71 #define R128_IDLE_RETRY 32 /* Fall out of idle loops after this count */
72 #define R128_TIMEOUT 2000000 /* Fall out of wait loops after this count */
73 #define R128_MMIOSIZE 0x4000
75 #define R128_VBIOS_SIZE 0x00010000
78 #define R128TRACE(x) \
80 ErrorF("(**) %s(%d): ", R128_NAME, pScrn->scrnIndex); \
89 #define R128_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
90 #define R128_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
91 #define R128PTR(pScrn) ((R128InfoPtr)(pScrn)->driverPrivate)
94 * \brief Chip families.
102 typedef struct { /* All values in XCLKS */
103 int ML
; /* Memory Read Latency */
104 int MB
; /* Memory Burst Length */
105 int Trcd
; /* RAS to CAS delay */
106 int Trp
; /* RAS percentage */
107 int Twr
; /* Write Recovery */
108 int CL
; /* CAS Latency */
109 int Tr2w
; /* Read to Write Delay */
110 int Rloop
; /* Loop Latency */
111 int Rloop_fudge
; /* Add to ML to get Rloop */
113 } R128RAMRec
, *R128RAMPtr
;
116 /* Common registers */
118 int32_t ovr_wid_left_right
;
119 int32_t ovr_wid_top_bottom
;
120 int32_t ov0_scale_cntl
;
121 int32_t mpp_tb_config
;
122 int32_t mpp_gp_config
;
124 int32_t viph_control
;
126 int32_t gen_int_cntl
;
127 int32_t cap0_trig_cntl
;
128 int32_t cap1_trig_cntl
;
132 /* Other registers to save for VT switches */
134 int32_t gen_reset_cntl
;
135 int32_t clock_cntl_index
;
136 int32_t amcgpio_en_reg
;
137 int32_t amcgpio_mask
;
140 int32_t crtc_gen_cntl
;
141 int32_t crtc_ext_cntl
;
143 int32_t crtc_h_total_disp
;
144 int32_t crtc_h_sync_strt_wid
;
145 int32_t crtc_v_total_disp
;
146 int32_t crtc_v_sync_strt_wid
;
148 int32_t crtc_offset_cntl
;
151 /* CRTC2 registers */
152 int32_t crtc2_gen_cntl
;
154 /* Flat panel registers */
155 int32_t fp_crtc_h_total_disp
;
156 int32_t fp_crtc_v_total_disp
;
158 int32_t fp_h_sync_strt_wid
;
159 int32_t fp_horz_stretch
;
160 int32_t fp_panel_cntl
;
161 int32_t fp_v_sync_strt_wid
;
162 int32_t fp_vert_stretch
;
163 int32_t lvds_gen_cntl
;
165 int32_t tmds_transmitter_cntl
;
167 /* Computed values for PLL */
168 int32_t dot_clock_freq
;
169 int32_t pll_output_freq
;
174 int32_t ppll_ref_div
;
183 GLboolean palette_valid
;
184 int32_t palette
[256];
185 } R128SaveRec
, *R128SavePtr
;
189 CARD16 reference_freq
;
190 CARD16 reference_div
;
191 int32_t min_pll_freq
;
192 int32_t max_pll_freq
;
194 } R128PLLRec
, *R128PLLPtr
;
217 unsigned long LinearAddr
; /* Frame buffer physical address */
218 unsigned long BIOSAddr
; /* BIOS physical address */
220 unsigned char *MMIO
; /* Map of MMIO region */
221 unsigned char *FB
; /* Map of frame buffer */
225 unsigned long FbMapSize
; /* Size of frame buffer, in bytes */
226 int Flags
; /* Saved copy of mode flags */
229 int8_t BIOSDisplay
; /* Device the BIOS is set to display to */
231 GLboolean HasPanelRegs
; /* Current chip can connect to a FP */
232 int8_t *VBIOS
; /* Video BIOS for mode validation on FPs */
233 int FPBIOSstart
; /* Start of the flat panel info */
235 /* Computed values for FPs */
249 R128SaveRec SavedReg
; /* Original (text) mode */
250 R128SaveRec ModeReg
; /* Current mode */
251 GLboolean (*CloseScreen
)(int, ScreenPtr
);
252 void (*BlockHandler
)(int, pointer
, pointer
, pointer
);
254 GLboolean PaletteSavedOnVT
; /* Palette saved on last VT switch */
258 xf86CursorInfoPtr cursor
;
260 unsigned long cursor_start
;
261 unsigned long cursor_end
;
264 * XAAForceTransBlit is used to change the behavior of the XAA
265 * SetupForScreenToScreenCopy function, to make it DGA-friendly.
267 GLboolean XAAForceTransBlit
;
269 int fifo_slots
; /* Free slots in the FIFO (64 max) */
270 int pix24bpp
; /* Depth of pixmap for 24bpp framebuffer */
271 GLboolean dac6bits
; /* Use 6 bit DAC? */
273 /* Computed values for Rage 128 */
276 int32_t dp_gui_master_cntl
;
278 /* Saved values for ScreenToScreenCopy */
282 /* ScanlineScreenToScreenColorExpand support */
283 unsigned char *scratch_buffer
[1];
284 unsigned char *scratch_save
;
299 int scanline_bpp
; /* Only used for ImageWrite */
305 int DGAViewportStatus
;
306 DGAFunctionRec DGAFuncs
;
308 R128FBLayout CurrentLayout
;
314 int numVisualConfigs
;
315 __GLXvisualConfig
*pVisualConfigs
;
316 R128ConfigPrivPtr pVisualConfigsPriv
;
319 drmSize registerSize
;
320 drmHandle registerHandle
;
322 GLboolean IsPCI
; /* Current card is a PCI card */
324 drmHandle pciMemHandle
;
325 unsigned char *PCI
; /* Map */
327 GLboolean allowPageFlip
; /* Enable 3d page flipping */
328 GLboolean have3DWindows
; /* Are there any 3d clients? */
332 drmHandle agpMemHandle
; /* Handle from drmAgpAlloc */
333 unsigned long agpOffset
;
334 unsigned char *AGP
; /* Map */
337 GLboolean CCEInUse
; /* CCE is currently active */
338 int CCEMode
; /* CCE mode that server/clients use */
339 int CCEFifoSize
; /* Size of the CCE command FIFO */
340 GLboolean CCESecure
; /* CCE security enabled */
341 int CCEusecTimeout
; /* CCE timeout in usecs */
343 /* CCE ring buffer data */
344 unsigned long ringStart
; /* Offset into AGP space */
345 drmHandle ringHandle
; /* Handle from drmAddMap */
346 drmSize ringMapSize
; /* Size of map */
347 int ringSize
; /* Size of ring (in MB) */
348 unsigned char *ring
; /* Map */
351 unsigned long ringReadOffset
; /* Offset into AGP space */
352 drmHandle ringReadPtrHandle
; /* Handle from drmAddMap */
353 drmSize ringReadMapSize
; /* Size of map */
354 unsigned char *ringReadPtr
; /* Map */
356 /* CCE vertex/indirect buffer data */
357 unsigned long bufStart
; /* Offset into AGP space */
358 drmHandle bufHandle
; /* Handle from drmAddMap */
359 drmSize bufMapSize
; /* Size of map */
360 int bufSize
; /* Size of buffers (in MB) */
361 unsigned char *buf
; /* Map */
362 int bufNumBufs
; /* Number of buffers */
363 drmBufMapPtr buffers
; /* Buffer map */
365 /* CCE AGP Texture data */
366 unsigned long agpTexStart
; /* Offset into AGP space */
367 drmHandle agpTexHandle
; /* Handle from drmAddMap */
368 drmSize agpTexMapSize
; /* Size of map */
369 int agpTexSize
; /* Size of AGP tex space (in MB) */
370 unsigned char *agpTex
; /* Map */
373 /* CCE 2D accleration */
374 drmBufPtr indirectBuffer
;
377 /* DRI screen private data */
396 /* Saved scissor values */
403 int32_t re_width_height
;
408 int32_t gen_int_cntl
;
414 XF86VideoAdaptorPtr adaptor
;
415 void (*VideoTimerCallback
)(ScrnInfoPtr
, Time
);
418 OptionInfoPtr Options
;
425 } R128InfoRec
, *R128InfoPtr
;
427 #define R128WaitForFifo(pScrn, entries) \
429 if (info->fifo_slots < entries) R128WaitForFifoFunction(pScrn, entries); \
430 info->fifo_slots -= entries; \
433 extern void r128WaitForFifoFunction(const DRIDriverContext
*ctx
, int entries
);
434 extern void r128WaitForIdle(const DRIDriverContext
*ctx
);
436 extern void r128WaitForVerticalSync(const DRIDriverContext
*ctx
);
438 extern GLboolean
r128AccelInit(const DRIDriverContext
*ctx
);
439 extern void r128EngineInit(const DRIDriverContext
*ctx
);
440 extern GLboolean
r128CursorInit(const DRIDriverContext
*ctx
);
441 extern GLboolean
r128DGAInit(const DRIDriverContext
*ctx
);
443 extern void r128InitVideo(const DRIDriverContext
*ctx
);
445 extern GLboolean
r128DRIScreenInit(const DRIDriverContext
*ctx
);
446 extern void r128DRICloseScreen(const DRIDriverContext
*ctx
);
447 extern GLboolean
r128DRIFinishScreenInit(const DRIDriverContext
*ctx
);
449 #define R128CCE_START(ctx, info) \
451 int _ret = drmCommandNone(ctx->drmFD, DRM_R128_CCE_START); \
454 "%s: CCE start %d\n", __FUNCTION__, _ret); \
458 #define R128CCE_STOP(ctx, info) \
460 int _ret = R128CCEStop(ctx); \
463 "%s: CCE stop %d\n", __FUNCTION__, _ret); \
467 #define R128CCE_RESET(ctx, info) \
469 if (info->directRenderingEnabled \
470 && R128CCE_USE_RING_BUFFER(info->CCEMode)) { \
471 int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_RESET); \
474 "%s: CCE reset %d\n", __FUNCTION__, _ret); \
480 #define CCE_PACKET0( reg, n ) \
481 (R128_CCE_PACKET0 | ((n) << 16) | ((reg) >> 2))
482 #define CCE_PACKET1( reg0, reg1 ) \
483 (R128_CCE_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
484 #define CCE_PACKET2() \
486 #define CCE_PACKET3( pkt, n ) \
487 (R128_CCE_PACKET3 | (pkt) | ((n) << 16))
490 #define R128_VERBOSE 0
492 #define RING_LOCALS int32_t *__head; int __count;
494 #define R128CCE_REFRESH(pScrn, info) \
496 if ( R128_VERBOSE ) { \
497 fprintf(stderr, "REFRESH( %d ) in %s\n", \
498 !info->CCEInUse , __FUNCTION__ ); \
500 if ( !info->CCEInUse ) { \
501 R128CCEWaitForIdle(pScrn); \
503 OUT_RING_REG( R128_RE_TOP_LEFT, info->re_top_left ); \
504 OUT_RING_REG( R128_RE_WIDTH_HEIGHT, info->re_width_height ); \
505 OUT_RING_REG( R128_AUX_SC_CNTL, info->aux_sc_cntl ); \
507 info->CCEInUse = TRUE; \
511 #define BEGIN_RING( n ) do { \
512 if ( R128_VERBOSE ) { \
514 "BEGIN_RING( %d ) in %s\n", n, __FUNCTION__ ); \
516 if ( !info->indirectBuffer ) { \
517 info->indirectBuffer = R128CCEGetBuffer( pScrn ); \
518 info->indirectStart = 0; \
519 } else if ( (info->indirectBuffer->used + 4*(n)) > \
520 info->indirectBuffer->total ) { \
521 R128CCEFlushIndirect( pScrn, 1 ); \
523 __head = (pointer)((char *)info->indirectBuffer->address + \
524 info->indirectBuffer->used); \
528 #define ADVANCE_RING() do { \
529 if ( R128_VERBOSE ) { \
531 "ADVANCE_RING() used: %d+%d=%d/%d\n", \
532 info->indirectBuffer->used - info->indirectStart, \
533 __count * sizeof(int32_t), \
534 info->indirectBuffer->used - info->indirectStart + \
535 __count * sizeof(int32_t), \
536 info->indirectBuffer->total - info->indirectStart ); \
538 info->indirectBuffer->used += __count * (int)sizeof(int32_t); \
541 #define OUT_RING( x ) do { \
542 if ( R128_VERBOSE ) { \
544 " OUT_RING( 0x%08x )\n", (unsigned int)(x) ); \
546 MMIO_OUT32(&__head[__count++], 0, (x)); \
549 #define OUT_RING_REG( reg, val ) \
551 OUT_RING( CCE_PACKET0( reg, 0 ) ); \
555 #define FLUSH_RING() \
557 if ( R128_VERBOSE ) \
559 "FLUSH_RING in %s\n", __FUNCTION__ ); \
560 if ( info->indirectBuffer ) { \
561 R128CCEFlushIndirect( pScrn, 0 ); \