Merge branch '7.8'
[mesa.git] / src / mesa / drivers / dri / r128 / server / r128.h
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 "dri_util.h"
41
42 #define R128_DEBUG 0 /* Turn off debugging output */
43 #define R128_IDLE_RETRY 32 /* Fall out of idle loops after this count */
44 #define R128_TIMEOUT 2000000 /* Fall out of wait loops after this count */
45 #define R128_MMIOSIZE 0x4000
46
47 #define R128_VBIOS_SIZE 0x00010000
48
49 #if R128_DEBUG
50 #define R128TRACE(x) \
51 do { \
52 ErrorF("(**) %s(%d): ", R128_NAME, pScrn->scrnIndex); \
53 ErrorF x; \
54 } while (0);
55 #else
56 #define R128TRACE(x)
57 #endif
58
59
60 /* Other macros */
61 #define R128_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
62 #define R128_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
63 #define R128PTR(pScrn) ((R128InfoPtr)(pScrn)->driverPrivate)
64
65 /**
66 * \brief Chip families.
67 */
68 typedef enum {
69 CHIP_FAMILY_UNKNOWN,
70 CHIP_FAMILY_R128_PCI,
71 CHIP_FAMILY_R128_AGP,
72 } R128ChipFamily;
73
74 typedef struct { /* All values in XCLKS */
75 int ML; /* Memory Read Latency */
76 int MB; /* Memory Burst Length */
77 int Trcd; /* RAS to CAS delay */
78 int Trp; /* RAS percentage */
79 int Twr; /* Write Recovery */
80 int CL; /* CAS Latency */
81 int Tr2w; /* Read to Write Delay */
82 int Rloop; /* Loop Latency */
83 int Rloop_fudge; /* Add to ML to get Rloop */
84 char *name;
85 } R128RAMRec, *R128RAMPtr;
86
87 typedef struct {
88 /* Common registers */
89 uint32_t ovr_clr;
90 uint32_t ovr_wid_left_right;
91 uint32_t ovr_wid_top_bottom;
92 uint32_t ov0_scale_cntl;
93 uint32_t mpp_tb_config;
94 uint32_t mpp_gp_config;
95 uint32_t subpic_cntl;
96 uint32_t viph_control;
97 uint32_t i2c_cntl_1;
98 uint32_t gen_int_cntl;
99 uint32_t cap0_trig_cntl;
100 uint32_t cap1_trig_cntl;
101 uint32_t bus_cntl;
102 uint32_t config_cntl;
103
104 /* Other registers to save for VT switches */
105 uint32_t dp_datatype;
106 uint32_t gen_reset_cntl;
107 uint32_t clock_cntl_index;
108 uint32_t amcgpio_en_reg;
109 uint32_t amcgpio_mask;
110
111 /* CRTC registers */
112 uint32_t crtc_gen_cntl;
113 uint32_t crtc_ext_cntl;
114 uint32_t dac_cntl;
115 uint32_t crtc_h_total_disp;
116 uint32_t crtc_h_sync_strt_wid;
117 uint32_t crtc_v_total_disp;
118 uint32_t crtc_v_sync_strt_wid;
119 uint32_t crtc_offset;
120 uint32_t crtc_offset_cntl;
121 uint32_t crtc_pitch;
122
123 /* CRTC2 registers */
124 uint32_t crtc2_gen_cntl;
125
126 /* Flat panel registers */
127 uint32_t fp_crtc_h_total_disp;
128 uint32_t fp_crtc_v_total_disp;
129 uint32_t fp_gen_cntl;
130 uint32_t fp_h_sync_strt_wid;
131 uint32_t fp_horz_stretch;
132 uint32_t fp_panel_cntl;
133 uint32_t fp_v_sync_strt_wid;
134 uint32_t fp_vert_stretch;
135 uint32_t lvds_gen_cntl;
136 uint32_t tmds_crc;
137 uint32_t tmds_transmitter_cntl;
138
139 /* Computed values for PLL */
140 uint32_t dot_clock_freq;
141 uint32_t pll_output_freq;
142 int feedback_div;
143 int post_div;
144
145 /* PLL registers */
146 uint32_t ppll_ref_div;
147 uint32_t ppll_div_3;
148 uint32_t htotal_cntl;
149
150 /* DDA register */
151 uint32_t dda_config;
152 uint32_t dda_on_off;
153
154 /* Pallet */
155 GLboolean palette_valid;
156 uint32_t palette[256];
157 } R128SaveRec, *R128SavePtr;
158
159 typedef struct {
160 int Chipset;
161 GLboolean Primary;
162
163 GLboolean FBDev;
164
165 unsigned long LinearAddr; /* Frame buffer physical address */
166 unsigned long BIOSAddr; /* BIOS physical address */
167
168 unsigned char *MMIO; /* Map of MMIO region */
169 unsigned char *FB; /* Map of frame buffer */
170
171 uint32_t MemCntl;
172 uint32_t BusCntl;
173 unsigned long FbMapSize; /* Size of frame buffer, in bytes */
174 int Flags; /* Saved copy of mode flags */
175
176 /* Computed values for FPs */
177 int PanelXRes;
178 int PanelYRes;
179 int HOverPlus;
180 int HSyncWidth;
181 int HBlank;
182 int VOverPlus;
183 int VSyncWidth;
184 int VBlank;
185 int PanelPwrDly;
186
187 unsigned long cursor_start;
188 unsigned long cursor_end;
189
190 /*
191 * XAAForceTransBlit is used to change the behavior of the XAA
192 * SetupForScreenToScreenCopy function, to make it DGA-friendly.
193 */
194 GLboolean XAAForceTransBlit;
195
196 int fifo_slots; /* Free slots in the FIFO (64 max) */
197 int pix24bpp; /* Depth of pixmap for 24bpp framebuffer */
198 GLboolean dac6bits; /* Use 6 bit DAC? */
199
200 /* Computed values for Rage 128 */
201 int pitch;
202 int datatype;
203 uint32_t dp_gui_master_cntl;
204
205 /* Saved values for ScreenToScreenCopy */
206 int xdir;
207 int ydir;
208
209 /* ScanlineScreenToScreenColorExpand support */
210 unsigned char *scratch_buffer[1];
211 unsigned char *scratch_save;
212 int scanline_x;
213 int scanline_y;
214 int scanline_w;
215 int scanline_h;
216
217 int scanline_hpass;
218 int scanline_x1clip;
219 int scanline_x2clip;
220 int scanline_rop;
221 int scanline_fg;
222 int scanline_bg;
223
224 int scanline_words;
225 int scanline_direct;
226 int scanline_bpp; /* Only used for ImageWrite */
227
228 drm_context_t drmCtx;
229
230 drmSize registerSize;
231 drm_handle_t registerHandle;
232
233 GLboolean IsPCI; /* Current card is a PCI card */
234 drmSize pciSize;
235 drm_handle_t pciMemHandle;
236 unsigned char *PCI; /* Map */
237
238 GLboolean allowPageFlip; /* Enable 3d page flipping */
239 GLboolean have3DWindows; /* Are there any 3d clients? */
240 int drmMinor;
241
242 drmSize agpSize;
243 drm_handle_t agpMemHandle; /* Handle from drmAgpAlloc */
244 unsigned long agpOffset;
245 unsigned char *AGP; /* Map */
246 int agpMode;
247
248 GLboolean CCEInUse; /* CCE is currently active */
249 int CCEMode; /* CCE mode that server/clients use */
250 int CCEFifoSize; /* Size of the CCE command FIFO */
251 GLboolean CCESecure; /* CCE security enabled */
252 int CCEusecTimeout; /* CCE timeout in usecs */
253
254 /* CCE ring buffer data */
255 unsigned long ringStart; /* Offset into AGP space */
256 drm_handle_t ringHandle; /* Handle from drmAddMap */
257 drmSize ringMapSize; /* Size of map */
258 int ringSize; /* Size of ring (in MB) */
259 unsigned char *ring; /* Map */
260 int ringSizeLog2QW;
261
262 unsigned long ringReadOffset; /* Offset into AGP space */
263 drm_handle_t ringReadPtrHandle; /* Handle from drmAddMap */
264 drmSize ringReadMapSize; /* Size of map */
265 unsigned char *ringReadPtr; /* Map */
266
267 /* CCE vertex/indirect buffer data */
268 unsigned long bufStart; /* Offset into AGP space */
269 drm_handle_t bufHandle; /* Handle from drmAddMap */
270 drmSize bufMapSize; /* Size of map */
271 int bufSize; /* Size of buffers (in MB) */
272 unsigned char *buf; /* Map */
273 int bufNumBufs; /* Number of buffers */
274 drmBufMapPtr buffers; /* Buffer map */
275
276 /* CCE AGP Texture data */
277 unsigned long agpTexStart; /* Offset into AGP space */
278 drm_handle_t agpTexHandle; /* Handle from drmAddMap */
279 drmSize agpTexMapSize; /* Size of map */
280 int agpTexSize; /* Size of AGP tex space (in MB) */
281 unsigned char *agpTex; /* Map */
282 int log2AGPTexGran;
283
284 /* CCE 2D accleration */
285 drmBufPtr indirectBuffer;
286 int indirectStart;
287
288 /* DRI screen private data */
289 int fbX;
290 int fbY;
291 int backX;
292 int backY;
293 int depthX;
294 int depthY;
295
296 int frontOffset;
297 int frontPitch;
298 int backOffset;
299 int backPitch;
300 int depthOffset;
301 int depthPitch;
302 int spanOffset;
303 int textureOffset;
304 int textureSize;
305 int log2TexGran;
306
307 /* Saved scissor values */
308 uint32_t sc_left;
309 uint32_t sc_right;
310 uint32_t sc_top;
311 uint32_t sc_bottom;
312
313 uint32_t re_top_left;
314 uint32_t re_width_height;
315
316 uint32_t aux_sc_cntl;
317
318 int irq;
319 uint32_t gen_int_cntl;
320
321 GLboolean DMAForXv;
322
323 } R128InfoRec, *R128InfoPtr;
324
325 #define R128WaitForFifo(pScrn, entries) \
326 do { \
327 if (info->fifo_slots < entries) R128WaitForFifoFunction(pScrn, entries); \
328 info->fifo_slots -= entries; \
329 } while (0)
330
331 extern void r128WaitForFifoFunction(const DRIDriverContext *ctx, int entries);
332 extern void r128WaitForIdle(const DRIDriverContext *ctx);
333
334 extern void r128WaitForVerticalSync(const DRIDriverContext *ctx);
335
336 extern GLboolean r128AccelInit(const DRIDriverContext *ctx);
337 extern void r128EngineInit(const DRIDriverContext *ctx);
338 extern GLboolean r128CursorInit(const DRIDriverContext *ctx);
339 extern GLboolean r128DGAInit(const DRIDriverContext *ctx);
340
341 extern void r128InitVideo(const DRIDriverContext *ctx);
342
343 extern GLboolean r128DRIScreenInit(const DRIDriverContext *ctx);
344 extern void r128DRICloseScreen(const DRIDriverContext *ctx);
345 extern GLboolean r128DRIFinishScreenInit(const DRIDriverContext *ctx);
346
347 #define R128CCE_START(ctx, info) \
348 do { \
349 int _ret = drmCommandNone(ctx->drmFD, DRM_R128_CCE_START); \
350 if (_ret) { \
351 fprintf(stderr, \
352 "%s: CCE start %d\n", __FUNCTION__, _ret); \
353 } \
354 } while (0)
355
356 #define R128CCE_STOP(ctx, info) \
357 do { \
358 int _ret = R128CCEStop(ctx); \
359 if (_ret) { \
360 fprintf(stderr, \
361 "%s: CCE stop %d\n", __FUNCTION__, _ret); \
362 } \
363 } while (0)
364
365 #define R128CCE_RESET(ctx, info) \
366 do { \
367 if (info->directRenderingEnabled \
368 && R128CCE_USE_RING_BUFFER(info->CCEMode)) { \
369 int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_RESET); \
370 if (_ret) { \
371 fprintf(stderr, \
372 "%s: CCE reset %d\n", __FUNCTION__, _ret); \
373 } \
374 } \
375 } while (0)
376
377
378 #define CCE_PACKET0( reg, n ) \
379 (R128_CCE_PACKET0 | ((n) << 16) | ((reg) >> 2))
380 #define CCE_PACKET1( reg0, reg1 ) \
381 (R128_CCE_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
382 #define CCE_PACKET2() \
383 (R128_CCE_PACKET2)
384 #define CCE_PACKET3( pkt, n ) \
385 (R128_CCE_PACKET3 | (pkt) | ((n) << 16))
386
387
388 #define R128_VERBOSE 0
389
390 #define RING_LOCALS uint32_t *__head; int __count;
391
392 #define R128CCE_REFRESH(pScrn, info) \
393 do { \
394 if ( R128_VERBOSE ) { \
395 fprintf(stderr, "REFRESH( %d ) in %s\n", \
396 !info->CCEInUse , __FUNCTION__ ); \
397 } \
398 if ( !info->CCEInUse ) { \
399 R128CCEWaitForIdle(pScrn); \
400 BEGIN_RING( 6 ); \
401 OUT_RING_REG( R128_RE_TOP_LEFT, info->re_top_left ); \
402 OUT_RING_REG( R128_RE_WIDTH_HEIGHT, info->re_width_height ); \
403 OUT_RING_REG( R128_AUX_SC_CNTL, info->aux_sc_cntl ); \
404 ADVANCE_RING(); \
405 info->CCEInUse = TRUE; \
406 } \
407 } while (0)
408
409 #define BEGIN_RING( n ) do { \
410 if ( R128_VERBOSE ) { \
411 fprintf(stderr, \
412 "BEGIN_RING( %d ) in %s\n", n, __FUNCTION__ ); \
413 } \
414 if ( !info->indirectBuffer ) { \
415 info->indirectBuffer = R128CCEGetBuffer( pScrn ); \
416 info->indirectStart = 0; \
417 } else if ( (info->indirectBuffer->used + 4*(n)) > \
418 info->indirectBuffer->total ) { \
419 R128CCEFlushIndirect( pScrn, 1 ); \
420 } \
421 __head = (pointer)((char *)info->indirectBuffer->address + \
422 info->indirectBuffer->used); \
423 __count = 0; \
424 } while (0)
425
426 #define ADVANCE_RING() do { \
427 if ( R128_VERBOSE ) { \
428 fprintf(stderr, \
429 "ADVANCE_RING() used: %d+%d=%d/%d\n", \
430 info->indirectBuffer->used - info->indirectStart, \
431 __count * sizeof(uint32_t), \
432 info->indirectBuffer->used - info->indirectStart + \
433 __count * sizeof(uint32_t), \
434 info->indirectBuffer->total - info->indirectStart ); \
435 } \
436 info->indirectBuffer->used += __count * (int)sizeof(uint32_t); \
437 } while (0)
438
439 #define OUT_RING( x ) do { \
440 if ( R128_VERBOSE ) { \
441 fprintf(stderr, \
442 " OUT_RING( 0x%08x )\n", (unsigned int)(x) ); \
443 } \
444 MMIO_OUT32(&__head[__count++], 0, (x)); \
445 } while (0)
446
447 #define OUT_RING_REG( reg, val ) \
448 do { \
449 OUT_RING( CCE_PACKET0( reg, 0 ) ); \
450 OUT_RING( val ); \
451 } while (0)
452
453 #define FLUSH_RING() \
454 do { \
455 if ( R128_VERBOSE ) \
456 fprintf(stderr, \
457 "FLUSH_RING in %s\n", __FUNCTION__ ); \
458 if ( info->indirectBuffer ) { \
459 R128CCEFlushIndirect( pScrn, 0 ); \
460 } \
461 } while (0)
462
463
464 #endif