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