#ifndef _RADEON_H_
#define _RADEON_H_
#include "xf86str.h"
#include "xf86Pci.h"
#include "xaa.h"
#include "xf86Cursor.h"
#include "xf86DDC.h"
#include "xf86xv.h"
#ifdef XF86DRI
#define _XF86DRI_SERVER_
#include "radeon_dripriv.h"
#include "dri.h"
#include "GL/glxint.h"
#endif
#ifdef RENDER
#include "picturestr.h"
#endif
#define RADEON_DEBUG 0
#define RADEON_IDLE_RETRY 16
#define RADEON_TIMEOUT 2000000
#define RADEON_MMIOSIZE 0x80000
#define RADEON_VBIOS_SIZE 0x00010000
#define RADEON_USE_RMX 0x80000000
#if RADEON_DEBUG
#define RADEONTRACE(x) \
do { \
ErrorF("(**) %s(%d): ", RADEON_NAME, pScrn->scrnIndex); \
ErrorF x; \
} while (0);
#else
#define RADEONTRACE(x)
#endif
#define RADEON_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
#define RADEONPTR(pScrn) ((RADEONInfoPtr)(pScrn)->driverPrivate)
typedef struct {
CARD32 ovr_clr;
CARD32 ovr_wid_left_right;
CARD32 ovr_wid_top_bottom;
CARD32 ov0_scale_cntl;
CARD32 mpp_tb_config;
CARD32 mpp_gp_config;
CARD32 subpic_cntl;
CARD32 viph_control;
CARD32 i2c_cntl_1;
CARD32 gen_int_cntl;
CARD32 cap0_trig_cntl;
CARD32 cap1_trig_cntl;
CARD32 bus_cntl;
CARD32 surface_cntl;
CARD32 bios_5_scratch;
CARD32 dp_datatype;
CARD32 rbbm_soft_reset;
CARD32 clock_cntl_index;
CARD32 amcgpio_en_reg;
CARD32 amcgpio_mask;
CARD32 crtc_gen_cntl;
CARD32 crtc_ext_cntl;
CARD32 dac_cntl;
CARD32 crtc_h_total_disp;
CARD32 crtc_h_sync_strt_wid;
CARD32 crtc_v_total_disp;
CARD32 crtc_v_sync_strt_wid;
CARD32 crtc_offset;
CARD32 crtc_offset_cntl;
CARD32 crtc_pitch;
CARD32 disp_merge_cntl;
CARD32 grph_buffer_cntl;
CARD32 crtc_more_cntl;
CARD32 crtc2_gen_cntl;
CARD32 dac2_cntl;
CARD32 disp_output_cntl;
CARD32 disp_hw_debug;
CARD32 disp2_merge_cntl;
CARD32 grph2_buffer_cntl;
CARD32 crtc2_h_total_disp;
CARD32 crtc2_h_sync_strt_wid;
CARD32 crtc2_v_total_disp;
CARD32 crtc2_v_sync_strt_wid;
CARD32 crtc2_offset;
CARD32 crtc2_offset_cntl;
CARD32 crtc2_pitch;
CARD32 fp_crtc_h_total_disp;
CARD32 fp_crtc_v_total_disp;
CARD32 fp_gen_cntl;
CARD32 fp2_gen_cntl;
CARD32 fp_h_sync_strt_wid;
CARD32 fp2_h_sync_strt_wid;
CARD32 fp_horz_stretch;
CARD32 fp_panel_cntl;
CARD32 fp_v_sync_strt_wid;
CARD32 fp2_v_sync_strt_wid;
CARD32 fp_vert_stretch;
CARD32 lvds_gen_cntl;
CARD32 lvds_pll_cntl;
CARD32 tmds_pll_cntl;
CARD32 tmds_transmitter_cntl;
CARD32 dot_clock_freq;
CARD32 pll_output_freq;
int feedback_div;
int post_div;
unsigned ppll_ref_div;
unsigned ppll_div_3;
CARD32 htotal_cntl;
CARD32 dot_clock_freq_2;
CARD32 pll_output_freq_2;
int feedback_div_2;
int post_div_2;
CARD32 p2pll_ref_div;
CARD32 p2pll_div_0;
CARD32 htotal_cntl2;
Bool palette_valid;
CARD32 palette[256];
CARD32 palette2[256];
} RADEONSaveRec, *RADEONSavePtr;
typedef struct {
CARD16 reference_freq;
CARD16 reference_div;
CARD32 min_pll_freq;
CARD32 max_pll_freq;
CARD16 xclk;
} RADEONPLLRec, *RADEONPLLPtr;
typedef struct {
int bitsPerPixel;
int depth;
int displayWidth;
int pixel_code;
int pixel_bytes;
DisplayModePtr mode;
} RADEONFBLayout;
typedef enum {
MT_NONE,
MT_CRT,
MT_LCD,
MT_DFP,
MT_CTV,
MT_STV
} RADEONMonitorType;
typedef enum {
DDC_NONE_DETECTED,
DDC_MONID,
DDC_DVI,
DDC_VGA,
DDC_CRT2
} RADEONDDCType;
typedef enum {
CONNECTOR_NONE,
CONNECTOR_PROPRIETARY,
CONNECTOR_CRT,
CONNECTOR_DVI_I,
CONNECTOR_DVI_D
} RADEONConnectorType;
typedef enum {
CHIP_FAMILY_UNKNOW,
CHIP_FAMILY_LEGACY,
CHIP_FAMILY_RADEON,
CHIP_FAMILY_RV100,
CHIP_FAMILY_RS100,
CHIP_FAMILY_RV200,
CHIP_FAMILY_RS200,
CHIP_FAMILY_R200,
CHIP_FAMILY_RV250,
CHIP_FAMILY_RS300,
CHIP_FAMILY_RV280,
CHIP_FAMILY_R300,
CHIP_FAMILY_R350,
CHIP_FAMILY_RV350,
CHIP_FAMILY_LAST
} RADEONChipFamily;
typedef struct {
CARD32 freq;
CARD32 value;
}RADEONTMDSPll;
typedef struct {
EntityInfoPtr pEnt;
pciVideoPtr PciInfo;
PCITAG PciTag;
int Chipset;
RADEONChipFamily ChipFamily;
Bool FBDev;
unsigned long LinearAddr;
unsigned long MMIOAddr;
unsigned long BIOSAddr;
unsigned char *MMIO;
unsigned char *FB;
CARD8 *VBIOS;
CARD32 MemCntl;
CARD32 BusCntl;
unsigned long FbMapSize;
int Flags;
RADEONMonitorType DisplayType;
RADEONDDCType DDCType;
RADEONConnectorType ConnectorType;
Bool HasCRTC2;
Bool IsMobility;
Bool IsIGP;
Bool IsSecondary;
Bool IsSwitching;
Bool Clone;
RADEONMonitorType CloneType;
RADEONDDCType CloneDDCType;
DisplayModePtr CloneModes;
DisplayModePtr CurCloneMode;
int CloneFrameX0;
int CloneFrameY0;
Bool OverlayOnCRTC2;
Bool PanelOff;
int FPBIOSstart;
Bool ddc_mode;
Bool R300CGWorkaround;
int PanelXRes;
int PanelYRes;
int HOverPlus;
int HSyncWidth;
int HBlank;
int VOverPlus;
int VSyncWidth;
int VBlank;
int PanelPwrDly;
int DotClock;
int RefDivider;
int FeedbackDivider;
int PostDivider;
Bool UseBiosDividers;
Bool ddc_bios;
Bool ddc1;
Bool ddc2;
I2CBusPtr pI2CBus;
CARD32 DDCReg;
RADEONPLLRec pll;
RADEONTMDSPll tmds_pll[4];
int RamWidth;
float sclk;
float mclk;
Bool IsDDR;
int DispPriority;
RADEONSaveRec SavedReg;
RADEONSaveRec ModeReg;
Bool (*CloseScreen)(int, ScreenPtr);
void (*BlockHandler)(int, pointer, pointer, pointer);
Bool PaletteSavedOnVT;
XAAInfoRecPtr accel;
Bool accelOn;
xf86CursorInfoPtr cursor;
unsigned long cursor_start;
unsigned long cursor_end;
#ifdef ARGB_CURSOR
Bool cursor_argb;
#endif
int cursor_fg;
int cursor_bg;
Bool XAAForceTransBlit;
int fifo_slots;
int pix24bpp;
Bool dac6bits;
int pitch;
int datatype;
CARD32 dp_gui_master_cntl;
CARD32 dp_gui_master_cntl_clip;
CARD32 trans_color;
int xdir;
int ydir;
unsigned char *scratch_buffer[1];
unsigned char *scratch_save;
int scanline_x;
int scanline_y;
int scanline_w;
int scanline_h;
int scanline_h_w;
int scanline_words;
int scanline_direct;
int scanline_bpp;
int scanline_fg;
int scanline_bg;
int scanline_hpass;
int scanline_x1clip;
int scanline_x2clip;
int dashLen;
CARD32 dashPattern;
int dash_fg;
int dash_bg;
DGAModePtr DGAModes;
int numDGAModes;
Bool DGAactive;
int DGAViewportStatus;
DGAFunctionRec DGAFuncs;
RADEONFBLayout CurrentLayout;
#ifdef XF86DRI
Bool noBackBuffer;
Bool directRenderingEnabled;
DRIInfoPtr pDRIInfo;
int drmFD;
int numVisualConfigs;
__GLXvisualConfig *pVisualConfigs;
RADEONConfigPrivPtr pVisualConfigsPriv;
drmHandle fbHandle;
drmSize registerSize;
drmHandle registerHandle;
Bool IsPCI;
drmSize pciSize;
drmHandle pciMemHandle;
unsigned char *PCI;
Bool depthMoves;
Bool allowPageFlip;
Bool have3DWindows;
int drmMinor;
drmSize gartSize;
drmHandle agpMemHandle;
unsigned long gartOffset;
unsigned char *AGP;
int agpMode;
int agpFastWrite;
CARD32 pciCommand;
Bool CPRuns;
Bool CPInUse;
Bool CPStarted;
int CPMode;
int CPFifoSize;
int CPusecTimeout;
unsigned long ringStart;
drmHandle ringHandle;
drmSize ringMapSize;
int ringSize;
unsigned char *ring;
int ringSizeLog2QW;
unsigned long ringReadOffset;
drmHandle ringReadPtrHandle;
drmSize ringReadMapSize;
unsigned char *ringReadPtr;
unsigned long bufStart;
drmHandle bufHandle;
drmSize bufMapSize;
int bufSize;
unsigned char *buf;
int bufNumBufs;
drmBufMapPtr buffers;
unsigned long gartTexStart;
drmHandle gartTexHandle;
drmSize gartTexMapSize;
int gartTexSize;
unsigned char *gartTex;
int log2GARTTexGran;
drmBufPtr indirectBuffer;
int indirectStart;
int fbX;
int fbY;
int backX;
int backY;
int depthX;
int depthY;
int frontOffset;
int frontPitch;
int backOffset;
int backPitch;
int depthOffset;
int depthPitch;
int textureOffset;
int textureSize;
int log2TexGran;
CARD32 frontPitchOffset;
CARD32 backPitchOffset;
CARD32 depthPitchOffset;
CARD32 dst_pitch_offset;
int backLines;
FBAreaPtr backArea;
int depthTexLines;
FBAreaPtr depthTexArea;
CARD32 sc_left;
CARD32 sc_right;
CARD32 sc_top;
CARD32 sc_bottom;
CARD32 re_top_left;
CARD32 re_width_height;
CARD32 aux_sc_cntl;
int irq;
#ifdef PER_CONTEXT_SAREA
int perctx_sarea_size;
#endif
#endif
XF86VideoAdaptorPtr adaptor;
void (*VideoTimerCallback)(ScrnInfoPtr, Time);
FBLinearPtr videoLinear;
int videoKey;
Bool showCache;
OptionInfoPtr Options;
#ifdef XFree86LOADER
XF86ModReqInfo xaaReq;
#endif
} RADEONInfoRec, *RADEONInfoPtr;
#define RADEONWaitForFifo(pScrn, entries) \
do { \
if (info->fifo_slots < entries) \
RADEONWaitForFifoFunction(pScrn, entries); \
info->fifo_slots -= entries; \
} while (0)
extern void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries);
extern void RADEONWaitForIdleMMIO(ScrnInfoPtr pScrn);
#ifdef XF86DRI
extern void RADEONWaitForIdleCP(ScrnInfoPtr pScrn);
#endif
extern void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y,
int clone);
extern void RADEONEngineReset(ScrnInfoPtr pScrn);
extern void RADEONEngineFlush(ScrnInfoPtr pScrn);
extern void RADEONEngineRestore(ScrnInfoPtr pScrn);
extern unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr);
extern void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn);
extern void RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn);
extern void RADEONSelectBuffer(ScrnInfoPtr pScrn, int buffer);
extern Bool RADEONAccelInit(ScreenPtr pScreen);
extern void RADEONEngineInit(ScrnInfoPtr pScrn);
extern Bool RADEONCursorInit(ScreenPtr pScreen);
extern Bool RADEONDGAInit(ScreenPtr pScreen);
extern int RADEONMinBits(int val);
extern void RADEONInitVideo(ScreenPtr pScreen);
extern void RADEONResetVideo(ScrnInfoPtr pScrn);
extern void R300CGWorkaround(ScrnInfoPtr pScrn);
#ifdef XF86DRI
extern Bool RADEONDRIScreenInit(ScreenPtr pScreen);
extern void RADEONDRICloseScreen(ScreenPtr pScreen);
extern void RADEONDRIResume(ScreenPtr pScreen);
extern Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen);
extern drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn);
extern void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard);
extern void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn);
extern int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info);
#define RADEONCP_START(pScrn, info) \
do { \
int _ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_START); \
if (_ret) { \
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
"%s: CP start %d\n", __FUNCTION__, _ret); \
} \
info->CPStarted = TRUE; \
} while (0)
#define RADEONCP_STOP(pScrn, info) \
do { \
int _ret; \
if (info->CPStarted) { \
_ret = RADEONCPStop(pScrn, info); \
if (_ret) { \
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
"%s: CP stop %d\n", __FUNCTION__, _ret); \
} \
info->CPStarted = FALSE; \
} \
RADEONEngineRestore(pScrn); \
info->CPRuns = FALSE; \
} while (0)
#define RADEONCP_RESET(pScrn, info) \
do { \
if (RADEONCP_USE_RING_BUFFER(info->CPMode)) { \
int _ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_RESET); \
if (_ret) { \
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
"%s: CP reset %d\n", __FUNCTION__, _ret); \
} \
} \
} while (0)
#define RADEONCP_REFRESH(pScrn, info) \
do { \
if (!info->CPInUse) { \
RADEON_WAIT_UNTIL_IDLE(); \
BEGIN_RING(6); \
OUT_RING_REG(RADEON_RE_TOP_LEFT, info->re_top_left); \
OUT_RING_REG(RADEON_RE_WIDTH_HEIGHT, info->re_width_height); \
OUT_RING_REG(RADEON_AUX_SC_CNTL, info->aux_sc_cntl); \
ADVANCE_RING(); \
info->CPInUse = TRUE; \
} \
} while (0)
#define CP_PACKET0(reg, n) \
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
#define CP_PACKET1(reg0, reg1) \
(RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
#define CP_PACKET2() \
(RADEON_CP_PACKET2)
#define CP_PACKET3(pkt, n) \
(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
#define RADEON_VERBOSE 0
#define RING_LOCALS CARD32 *__head = NULL; int __count = 0
#define BEGIN_RING(n) do { \
if (RADEON_VERBOSE) { \
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
"BEGIN_RING(%d) in %s\n", n, __FUNCTION__); \
} \
if (!info->indirectBuffer) { \
info->indirectBuffer = RADEONCPGetBuffer(pScrn); \
info->indirectStart = 0; \
} else if (info->indirectBuffer->used + (n) * (int)sizeof(CARD32) > \
info->indirectBuffer->total) { \
RADEONCPFlushIndirect(pScrn, 1); \
} \
__head = (pointer)((char *)info->indirectBuffer->address + \
info->indirectBuffer->used); \
__count = 0; \
} while (0)
#define ADVANCE_RING() do { \
if (RADEON_VERBOSE) { \
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
"ADVANCE_RING() start: %d used: %d count: %d\n", \
info->indirectStart, \
info->indirectBuffer->used, \
__count * (int)sizeof(CARD32)); \
} \
info->indirectBuffer->used += __count * (int)sizeof(CARD32); \
} while (0)
#define OUT_RING(x) do { \
if (RADEON_VERBOSE) { \
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
" OUT_RING(0x%08x)\n", (unsigned int)(x)); \
} \
__head[__count++] = (x); \
} while (0)
#define OUT_RING_REG(reg, val) \
do { \
OUT_RING(CP_PACKET0(reg, 0)); \
OUT_RING(val); \
} while (0)
#define FLUSH_RING() \
do { \
if (RADEON_VERBOSE) \
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
"FLUSH_RING in %s\n", __FUNCTION__); \
if (info->indirectBuffer) { \
RADEONCPFlushIndirect(pScrn, 0); \
} \
} while (0)
#define RADEON_WAIT_UNTIL_2D_IDLE() \
do { \
BEGIN_RING(2); \
OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); \
OUT_RING((RADEON_WAIT_2D_IDLECLEAN | \
RADEON_WAIT_HOST_IDLECLEAN)); \
ADVANCE_RING(); \
} while (0)
#define RADEON_WAIT_UNTIL_3D_IDLE() \
do { \
BEGIN_RING(2); \
OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); \
OUT_RING((RADEON_WAIT_3D_IDLECLEAN | \
RADEON_WAIT_HOST_IDLECLEAN)); \
ADVANCE_RING(); \
} while (0)
#define RADEON_WAIT_UNTIL_IDLE() \
do { \
if (RADEON_VERBOSE) { \
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
"WAIT_UNTIL_IDLE() in %s\n", __FUNCTION__); \
} \
BEGIN_RING(2); \
OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); \
OUT_RING((RADEON_WAIT_2D_IDLECLEAN | \
RADEON_WAIT_3D_IDLECLEAN | \
RADEON_WAIT_HOST_IDLECLEAN)); \
ADVANCE_RING(); \
} while (0)
#define RADEON_FLUSH_CACHE() \
do { \
BEGIN_RING(2); \
OUT_RING(CP_PACKET0(RADEON_RB2D_DSTCACHE_CTLSTAT, 0)); \
OUT_RING(RADEON_RB2D_DC_FLUSH); \
ADVANCE_RING(); \
} while (0)
#define RADEON_PURGE_CACHE() \
do { \
BEGIN_RING(2); \
OUT_RING(CP_PACKET0(RADEON_RB2D_DSTCACHE_CTLSTAT, 0)); \
OUT_RING(RADEON_RB2D_DC_FLUSH_ALL); \
ADVANCE_RING(); \
} while (0)
#endif
#endif