r128.h revision c582b7e3
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 Bool FBDev; 234 235 unsigned long LinearAddr; /* Frame buffer physical address */ 236 unsigned long MMIOAddr; /* MMIO region physical address */ 237 unsigned long BIOSAddr; /* BIOS physical address */ 238 239 void *MMIO; /* Map of MMIO region */ 240 void *FB; /* Map of frame buffer */ 241 242 CARD32 MemCntl; 243 CARD32 BusCntl; 244 unsigned long FbMapSize; /* Size of frame buffer, in bytes */ 245 int Flags; /* Saved copy of mode flags */ 246 247 CARD8 BIOSDisplay; /* Device the BIOS is set to display to */ 248 249 Bool HasPanelRegs; /* Current chip can connect to a FP */ 250 CARD8 *VBIOS; /* Video BIOS for mode validation on FPs */ 251 int FPBIOSstart; /* Start of the flat panel info */ 252 253 /* Computed values for FPs */ 254 int PanelXRes; 255 int PanelYRes; 256 int HOverPlus; 257 int HSyncWidth; 258 int HBlank; 259 int VOverPlus; 260 int VSyncWidth; 261 int VBlank; 262 int PanelPwrDly; 263 264 R128PLLRec pll; 265 R128RAMPtr ram; 266 267 R128SaveRec SavedReg; /* Original (text) mode */ 268 R128SaveRec ModeReg; /* Current mode */ 269 Bool (*CloseScreen)(int, ScreenPtr); 270 void (*BlockHandler)(int, pointer, pointer, pointer); 271 272 Bool PaletteSavedOnVT; /* Palette saved on last VT switch */ 273 274 XAAInfoRecPtr accel; 275 Bool accelOn; 276 xf86CursorInfoPtr cursor; 277 unsigned long cursor_start; 278 unsigned long cursor_end; 279 280 /* 281 * XAAForceTransBlit is used to change the behavior of the XAA 282 * SetupForScreenToScreenCopy function, to make it DGA-friendly. 283 */ 284 Bool XAAForceTransBlit; 285 286 int fifo_slots; /* Free slots in the FIFO (64 max) */ 287 int pix24bpp; /* Depth of pixmap for 24bpp framebuffer */ 288 Bool dac6bits; /* Use 6 bit DAC? */ 289 290 /* Computed values for Rage 128 */ 291 int pitch; 292 int datatype; 293 CARD32 dp_gui_master_cntl; 294 295 /* Saved values for ScreenToScreenCopy */ 296 int xdir; 297 int ydir; 298 299 /* ScanlineScreenToScreenColorExpand support */ 300 unsigned char *scratch_buffer[1]; 301 unsigned char *scratch_save; 302 int scanline_x; 303 int scanline_y; 304 int scanline_w; 305 int scanline_h; 306#ifdef XF86DRI 307 int scanline_hpass; 308 int scanline_x1clip; 309 int scanline_x2clip; 310 int scanline_rop; 311 int scanline_fg; 312 int scanline_bg; 313#endif /* XF86DRI */ 314 int scanline_words; 315 int scanline_direct; 316 int scanline_bpp; /* Only used for ImageWrite */ 317 318 DGAModePtr DGAModes; 319 int numDGAModes; 320 Bool DGAactive; 321 int DGAViewportStatus; 322 DGAFunctionRec DGAFuncs; 323 324 R128FBLayout CurrentLayout; 325#ifdef XF86DRI 326 Bool directRenderingEnabled; 327 DRIInfoPtr pDRIInfo; 328 int drmFD; 329 drm_context_t drmCtx; 330 int numVisualConfigs; 331 __GLXvisualConfig *pVisualConfigs; 332 R128ConfigPrivPtr pVisualConfigsPriv; 333 334 drm_handle_t fbHandle; 335 336 drmSize registerSize; 337 drm_handle_t registerHandle; 338 339 Bool IsPCI; /* Current card is a PCI card */ 340 drmSize pciSize; 341 drm_handle_t pciMemHandle; 342 drmAddress PCI; /* Map */ 343 344 Bool allowPageFlip; /* Enable 3d page flipping */ 345 Bool have3DWindows; /* Are there any 3d clients? */ 346 int drmMinor; 347 348 drmSize agpSize; 349 drm_handle_t agpMemHandle; /* Handle from drmAgpAlloc */ 350 unsigned long agpOffset; 351 drmAddress AGP; /* Map */ 352 int agpMode; 353 354 Bool CCEInUse; /* CCE is currently active */ 355 int CCEMode; /* CCE mode that server/clients use */ 356 int CCEFifoSize; /* Size of the CCE command FIFO */ 357 Bool CCESecure; /* CCE security enabled */ 358 int CCEusecTimeout; /* CCE timeout in usecs */ 359 360 /* CCE ring buffer data */ 361 unsigned long ringStart; /* Offset into AGP space */ 362 drm_handle_t ringHandle; /* Handle from drmAddMap */ 363 drmSize ringMapSize; /* Size of map */ 364 int ringSize; /* Size of ring (in MB) */ 365 drmAddress ring; /* Map */ 366 int ringSizeLog2QW; 367 368 unsigned long ringReadOffset; /* Offset into AGP space */ 369 drm_handle_t ringReadPtrHandle; /* Handle from drmAddMap */ 370 drmSize ringReadMapSize; /* Size of map */ 371 drmAddress ringReadPtr; /* Map */ 372 373 /* CCE vertex/indirect buffer data */ 374 unsigned long bufStart; /* Offset into AGP space */ 375 drm_handle_t bufHandle; /* Handle from drmAddMap */ 376 drmSize bufMapSize; /* Size of map */ 377 int bufSize; /* Size of buffers (in MB) */ 378 drmAddress buf; /* Map */ 379 int bufNumBufs; /* Number of buffers */ 380 drmBufMapPtr buffers; /* Buffer map */ 381 382 /* CCE AGP Texture data */ 383 unsigned long agpTexStart; /* Offset into AGP space */ 384 drm_handle_t agpTexHandle; /* Handle from drmAddMap */ 385 drmSize agpTexMapSize; /* Size of map */ 386 int agpTexSize; /* Size of AGP tex space (in MB) */ 387 drmAddress agpTex; /* Map */ 388 int log2AGPTexGran; 389 390 /* CCE 2D accleration */ 391 drmBufPtr indirectBuffer; 392 int indirectStart; 393 394 /* DRI screen private data */ 395 int fbX; 396 int fbY; 397 int backX; 398 int backY; 399 int depthX; 400 int depthY; 401 402 int frontOffset; 403 int frontPitch; 404 int backOffset; 405 int backPitch; 406 int depthOffset; 407 int depthPitch; 408 int spanOffset; 409 int textureOffset; 410 int textureSize; 411 int log2TexGran; 412 413 /* Saved scissor values */ 414 CARD32 sc_left; 415 CARD32 sc_right; 416 CARD32 sc_top; 417 CARD32 sc_bottom; 418 419 CARD32 re_top_left; 420 CARD32 re_width_height; 421 422 CARD32 aux_sc_cntl; 423 424 int irq; 425 CARD32 gen_int_cntl; 426 427 Bool DMAForXv; 428#endif 429 430 XF86VideoAdaptorPtr adaptor; 431 void (*VideoTimerCallback)(ScrnInfoPtr, Time); 432 int videoKey; 433 Bool showCache; 434 OptionInfoPtr Options; 435 436 Bool isDFP; 437 Bool isPro2; 438 I2CBusPtr pI2CBus; 439 CARD32 DDCReg; 440 441 Bool VGAAccess; 442 443 /****** Added for dualhead support *******************/ 444 BOOL HasCRTC2; /* M3/M4 */ 445 BOOL IsSecondary; /* second Screen */ 446 BOOL IsPrimary; /* primary Screen */ 447 BOOL UseCRT; /* force use CRT port as primary */ 448 BOOL SwitchingMode; 449 R128MonitorType DisplayType; /* Monitor connected on*/ 450 451} R128InfoRec, *R128InfoPtr; 452 453#define R128WaitForFifo(pScrn, entries) \ 454do { \ 455 if (info->fifo_slots < entries) R128WaitForFifoFunction(pScrn, entries); \ 456 info->fifo_slots -= entries; \ 457} while (0) 458 459extern R128EntPtr R128EntPriv(ScrnInfoPtr pScrn); 460extern void R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries); 461extern void R128WaitForIdle(ScrnInfoPtr pScrn); 462extern void R128EngineReset(ScrnInfoPtr pScrn); 463extern void R128EngineFlush(ScrnInfoPtr pScrn); 464 465extern unsigned R128INPLL(ScrnInfoPtr pScrn, int addr); 466extern void R128WaitForVerticalSync(ScrnInfoPtr pScrn); 467 468extern Bool R128AccelInit(ScreenPtr pScreen); 469extern void R128EngineInit(ScrnInfoPtr pScrn); 470extern Bool R128CursorInit(ScreenPtr pScreen); 471extern Bool R128DGAInit(ScreenPtr pScreen); 472 473extern int R128MinBits(int val); 474 475extern void R128InitVideo(ScreenPtr pScreen); 476 477#ifdef XF86DRI 478extern Bool R128DRIScreenInit(ScreenPtr pScreen); 479extern void R128DRICloseScreen(ScreenPtr pScreen); 480extern Bool R128DRIFinishScreenInit(ScreenPtr pScreen); 481 482#define R128CCE_START(pScrn, info) \ 483do { \ 484 int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_START); \ 485 if (_ret) { \ 486 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ 487 "%s: CCE start %d\n", __FUNCTION__, _ret); \ 488 } \ 489} while (0) 490 491#define R128CCE_STOP(pScrn, info) \ 492do { \ 493 int _ret = R128CCEStop(pScrn); \ 494 if (_ret) { \ 495 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ 496 "%s: CCE stop %d\n", __FUNCTION__, _ret); \ 497 } \ 498} while (0) 499 500#define R128CCE_RESET(pScrn, info) \ 501do { \ 502 if (info->directRenderingEnabled \ 503 && R128CCE_USE_RING_BUFFER(info->CCEMode)) { \ 504 int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_RESET); \ 505 if (_ret) { \ 506 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ 507 "%s: CCE reset %d\n", __FUNCTION__, _ret); \ 508 } \ 509 } \ 510} while (0) 511 512extern drmBufPtr R128CCEGetBuffer(ScrnInfoPtr pScrn); 513#endif 514 515extern void R128CCEFlushIndirect(ScrnInfoPtr pScrn, int discard); 516extern void R128CCEReleaseIndirect(ScrnInfoPtr pScrn); 517extern void R128CCEWaitForIdle(ScrnInfoPtr pScrn); 518extern int R128CCEStop(ScrnInfoPtr pScrn); 519 520 521#define CCE_PACKET0( reg, n ) \ 522 (R128_CCE_PACKET0 | ((n) << 16) | ((reg) >> 2)) 523#define CCE_PACKET1( reg0, reg1 ) \ 524 (R128_CCE_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2)) 525#define CCE_PACKET2() \ 526 (R128_CCE_PACKET2) 527#define CCE_PACKET3( pkt, n ) \ 528 (R128_CCE_PACKET3 | (pkt) | ((n) << 16)) 529 530 531#define R128_VERBOSE 0 532 533#define RING_LOCALS CARD32 *__head; int __count; 534 535#define R128CCE_REFRESH(pScrn, info) \ 536do { \ 537 if ( R128_VERBOSE ) { \ 538 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "REFRESH( %d ) in %s\n", \ 539 !info->CCEInUse , __FUNCTION__ ); \ 540 } \ 541 if ( !info->CCEInUse ) { \ 542 R128CCEWaitForIdle(pScrn); \ 543 BEGIN_RING( 6 ); \ 544 OUT_RING_REG( R128_RE_TOP_LEFT, info->re_top_left ); \ 545 OUT_RING_REG( R128_RE_WIDTH_HEIGHT, info->re_width_height ); \ 546 OUT_RING_REG( R128_AUX_SC_CNTL, info->aux_sc_cntl ); \ 547 ADVANCE_RING(); \ 548 info->CCEInUse = TRUE; \ 549 } \ 550} while (0) 551 552#define BEGIN_RING( n ) do { \ 553 if ( R128_VERBOSE ) { \ 554 xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ 555 "BEGIN_RING( %d ) in %s\n", n, __FUNCTION__ ); \ 556 } \ 557 if ( !info->indirectBuffer ) { \ 558 info->indirectBuffer = R128CCEGetBuffer( pScrn ); \ 559 info->indirectStart = 0; \ 560 } else if ( (info->indirectBuffer->used + 4*(n)) > \ 561 info->indirectBuffer->total ) { \ 562 R128CCEFlushIndirect( pScrn, 1 ); \ 563 } \ 564 __head = (pointer)((char *)info->indirectBuffer->address + \ 565 info->indirectBuffer->used); \ 566 __count = 0; \ 567} while (0) 568 569#define ADVANCE_RING() do { \ 570 if ( R128_VERBOSE ) { \ 571 xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ 572 "ADVANCE_RING() used: %d+%d=%d/%d\n", \ 573 info->indirectBuffer->used - info->indirectStart, \ 574 __count * (int)sizeof(CARD32), \ 575 info->indirectBuffer->used - info->indirectStart + \ 576 __count * (int)sizeof(CARD32), \ 577 info->indirectBuffer->total - info->indirectStart ); \ 578 } \ 579 info->indirectBuffer->used += __count * (int)sizeof(CARD32); \ 580} while (0) 581 582#define OUT_RING( x ) do { \ 583 if ( R128_VERBOSE ) { \ 584 xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ 585 " OUT_RING( 0x%08x )\n", (unsigned int)(x) ); \ 586 } \ 587 MMIO_OUT32(&__head[__count++], 0, (x)); \ 588} while (0) 589 590#define OUT_RING_REG( reg, val ) \ 591do { \ 592 OUT_RING( CCE_PACKET0( reg, 0 ) ); \ 593 OUT_RING( val ); \ 594} while (0) 595 596#define FLUSH_RING() \ 597do { \ 598 if ( R128_VERBOSE ) \ 599 xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ 600 "FLUSH_RING in %s\n", __FUNCTION__ ); \ 601 if ( info->indirectBuffer ) { \ 602 R128CCEFlushIndirect( pScrn, 0 ); \ 603 } \ 604} while (0) 605 606#endif 607