⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radeon_dri.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
/** * \file server/radeon_dri.c * \brief File to perform the device-specific initialization tasks typically * done in the X server. * * Here they are converted to run in the client (or perhaps a standalone * process), and to work with the frame buffer device rather than the X * server infrastructure. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <unistd.h>#include "driver.h"#include "drm.h"#include "memops.h"#include "radeon.h"#include "radeon_dri.h"#include "radeon_macros.h"#include "radeon_reg.h"#include "drm_sarea.h"static size_t radeon_drm_page_size;static int RadeonSetParam(const DRIDriverContext *ctx, int param, int value){   drm_radeon_setparam_t sp;   memset(&sp, 0, sizeof(sp));   sp.param = param;   sp.value = value;   if (drmCommandWrite(ctx->drmFD, DRM_RADEON_SETPARAM, &sp, sizeof(sp))) {     return -1;   }   return 0;}/** * \brief Wait for free FIFO entries. * * \param ctx display handle. * \param entries number of free entries to wait. * * It polls the free entries from the chip until it reaches the requested value * or a timeout (3000 tries) occurs. Aborts the program if the FIFO times out. */static void RADEONWaitForFifo( const DRIDriverContext *ctx,			       int entries ){   unsigned char *RADEONMMIO = ctx->MMIOAddress;   int i;   for (i = 0; i < 3000; i++) {      int fifo_slots =	 INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK;      if (fifo_slots >= entries) return;   }   /* There are recoveries possible, but I haven't seen them work    * in practice:    */   fprintf(stderr, "FIFO timed out: %d entries, stat=0x%08x\n",	   INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,	   INREG(RADEON_RBBM_STATUS));   exit(1);}/** * \brief Read a PLL register. * * \param ctx display handle. * \param addr PLL register index. * * \return value of the PLL register. */static unsigned int RADEONINPLL( const DRIDriverContext *ctx, int addr){    unsigned char *RADEONMMIO = ctx->MMIOAddress;    unsigned int data;    OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f);    data = INREG(RADEON_CLOCK_CNTL_DATA);    return data;}/** * \brief Reset graphics card to known state. * * \param ctx display handle. * * Resets the values of several Radeon registers. */static void RADEONEngineReset( const DRIDriverContext *ctx ){   unsigned char *RADEONMMIO = ctx->MMIOAddress;   unsigned int clock_cntl_index;   unsigned int mclk_cntl;   unsigned int rbbm_soft_reset;   unsigned int host_path_cntl;   int i;   OUTREGP(RADEON_RB2D_DSTCACHE_CTLSTAT,	   RADEON_RB2D_DC_FLUSH_ALL,	   ~RADEON_RB2D_DC_FLUSH_ALL);   for (i = 0; i < 512; i++) {      if (!(INREG(RADEON_RB2D_DSTCACHE_CTLSTAT) & RADEON_RB2D_DC_BUSY))	 break;   }   clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);   mclk_cntl = INPLL(ctx, RADEON_MCLK_CNTL);   OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl |			     RADEON_FORCEON_MCLKA |			     RADEON_FORCEON_MCLKB |			     RADEON_FORCEON_YCLKA |			     RADEON_FORCEON_YCLKB |			     RADEON_FORCEON_MC |			     RADEON_FORCEON_AIC));   /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some    * unexpected behaviour on some machines.  Here we use    * RADEON_HOST_PATH_CNTL to reset it.    */   host_path_cntl = INREG(RADEON_HOST_PATH_CNTL);   rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);   OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |				   RADEON_SOFT_RESET_CP |				   RADEON_SOFT_RESET_HI |				   RADEON_SOFT_RESET_SE |				   RADEON_SOFT_RESET_RE |				   RADEON_SOFT_RESET_PP |				   RADEON_SOFT_RESET_E2 |				   RADEON_SOFT_RESET_RB));   INREG(RADEON_RBBM_SOFT_RESET);   OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & 				   (unsigned int) ~(RADEON_SOFT_RESET_CP |						    RADEON_SOFT_RESET_HI |						    RADEON_SOFT_RESET_SE |						    RADEON_SOFT_RESET_RE |						    RADEON_SOFT_RESET_PP |						    RADEON_SOFT_RESET_E2 |						    RADEON_SOFT_RESET_RB)));   INREG(RADEON_RBBM_SOFT_RESET);   OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl | RADEON_HDP_SOFT_RESET);   INREG(RADEON_HOST_PATH_CNTL);   OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl);   OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);   OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);   OUTPLL(RADEON_MCLK_CNTL, mclk_cntl);}/** * \brief Restore the drawing engine. * * \param ctx display handle * * Resets the graphics card and sets initial values for several registers of * the card's drawing engine. * * Turns on the radeon command processor engine (i.e., the ringbuffer). */static int RADEONEngineRestore( const DRIDriverContext *ctx ){   RADEONInfoPtr info = ctx->driverPrivate;   unsigned char *RADEONMMIO = ctx->MMIOAddress;   int pitch64, datatype, dp_gui_master_cntl, err;   fprintf(stderr, "%s\n", __FUNCTION__);   OUTREG(RADEON_RB3D_CNTL, 0);   RADEONEngineReset( ctx );   switch (ctx->bpp) {   case 16: datatype = 4; break;   case 32: datatype = 6; break;   default: return 0;   }   dp_gui_master_cntl =      ((datatype << RADEON_GMC_DST_DATATYPE_SHIFT)       | RADEON_GMC_CLR_CMP_CNTL_DIS);   pitch64 = ((ctx->shared.virtualWidth * (ctx->bpp / 8) + 0x3f)) >> 6;   RADEONWaitForFifo(ctx, 1);   OUTREG(RADEON_DEFAULT_OFFSET, ((INREG(RADEON_DEFAULT_OFFSET) & 0xC0000000)				  | (pitch64 << 22)));   RADEONWaitForFifo(ctx, 1);   OUTREG(RADEON_SURFACE_CNTL, RADEON_SURF_TRANSLATION_DIS);    RADEONWaitForFifo(ctx, 1);   OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX					   | RADEON_DEFAULT_SC_BOTTOM_MAX));   RADEONWaitForFifo(ctx, 1);   OUTREG(RADEON_DP_GUI_MASTER_CNTL, (dp_gui_master_cntl				      | RADEON_GMC_BRUSH_SOLID_COLOR				      | RADEON_GMC_SRC_DATATYPE_COLOR));   RADEONWaitForFifo(ctx, 7);   OUTREG(RADEON_DST_LINE_START,    0);   OUTREG(RADEON_DST_LINE_END,      0);   OUTREG(RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);   OUTREG(RADEON_DP_BRUSH_BKGD_CLR, 0);   OUTREG(RADEON_DP_SRC_FRGD_CLR,   0xffffffff);   OUTREG(RADEON_DP_SRC_BKGD_CLR,   0);   OUTREG(RADEON_DP_WRITE_MASK,     0xffffffff);   OUTREG(RADEON_AUX_SC_CNTL,       0);/*    RADEONWaitForIdleMMIO(ctx); */   usleep(100);    OUTREG(RADEON_GEN_INT_CNTL, info->gen_int_cntl);   if (info->colorTiling)	   info->crtc_offset_cntl |= RADEON_CRTC_TILE_EN;   OUTREG(RADEON_CRTC_OFFSET_CNTL, info->crtc_offset_cntl);   /* Initialize and start the CP if required */   if ((err = drmCommandNone(ctx->drmFD, DRM_RADEON_CP_START)) != 0) {      fprintf(stderr, "%s: CP start %d\n", __FUNCTION__, err);      return 0;   }   return 1;}/** * \brief Shutdown the drawing engine. * * \param ctx display handle * * Turns off the command processor engine & restores the graphics card * to a state that fbdev understands. */static int RADEONEngineShutdown( const DRIDriverContext *ctx ){   drm_radeon_cp_stop_t  stop;   int              ret, i;   stop.flush = 1;   stop.idle  = 1;   ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP, &stop, 			 sizeof(drm_radeon_cp_stop_t));   if (ret == 0) {      return 0;   } else if (errno != EBUSY) {      return -errno;   }   stop.flush = 0;    i = 0;   do {      ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP, &stop, 			    sizeof(drm_radeon_cp_stop_t));   } while (ret && errno == EBUSY && i++ < 10);   if (ret == 0) {      return 0;   } else if (errno != EBUSY) {      return -errno;   }   stop.idle = 0;   if (drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP,		       &stop, sizeof(drm_radeon_cp_stop_t))) {      return -errno;   } else {      return 0;   }}/** * \brief Compute base 2 logarithm. * * \param val value. *  * \return base 2 logarithm of \p val. */static int RADEONMinBits(int val){   int  bits;   if (!val) return 1;   for (bits = 0; val; val >>= 1, ++bits);   return bits;}/** * \brief Initialize the AGP state * * \param ctx display handle. * \param info driver private data. * * \return one on success, or zero on failure. *  * Acquires and enables the AGP device. Reserves memory in the AGP space for * the ring buffer, vertex buffers and textures. Initialize the Radeon * registers to point to that memory and add client mappings. */static int RADEONDRIAgpInit( const DRIDriverContext *ctx, RADEONInfoPtr info){   unsigned char *RADEONMMIO = ctx->MMIOAddress;   unsigned long  mode;   int            ret;   int            s, l;   if (drmAgpAcquire(ctx->drmFD) < 0) {      fprintf(stderr, "[gart] AGP not available\n");      return 0;   }       /* Modify the mode if the default mode is not appropriate for this    * particular combination of graphics card and AGP chipset.    */   mode   = drmAgpGetMode(ctx->drmFD);	/* Default mode */   /* Disable fast write entirely - too many lockups.    */   mode &= ~RADEON_AGP_MODE_MASK;   switch (ctx->agpmode) {   case 4:          mode |= RADEON_AGP_4X_MODE;   case 2:          mode |= RADEON_AGP_2X_MODE;   case 1: default: mode |= RADEON_AGP_1X_MODE;   }   if (drmAgpEnable(ctx->drmFD, mode) < 0) {      fprintf(stderr, "[gart] AGP not enabled\n");      drmAgpRelease(ctx->drmFD);      return 0;   }   else     fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode);   /* Workaround for some hardware bugs */   if (info->ChipFamily < CHIP_FAMILY_R200)      OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000);   info->gartOffset = 0;   if ((ret = drmAgpAlloc(ctx->drmFD, info->gartSize*1024*1024, 0, NULL,			  &info->gartMemHandle)) < 0) {      fprintf(stderr, "[gart] Out of memory (%d)\n", ret);      drmAgpRelease(ctx->drmFD);      return 0;   }   fprintf(stderr,	   "[gart] %d kB allocated with handle 0x%08x\n",	   info->gartSize*1024, (unsigned)info->gartMemHandle);       if (drmAgpBind(ctx->drmFD,		  info->gartMemHandle, info->gartOffset) < 0) {      fprintf(stderr, "[gart] Could not bind\n");      drmAgpFree(ctx->drmFD, info->gartMemHandle);      drmAgpRelease(ctx->drmFD);      return 0;   }   /* Initialize the CP ring buffer data */   info->ringStart       = info->gartOffset;   info->ringMapSize     = info->ringSize*1024*1024 + radeon_drm_page_size;   info->ringReadOffset  = info->ringStart + info->ringMapSize;   info->ringReadMapSize = radeon_drm_page_size;   /* Reserve space for vertex/indirect buffers */   info->bufStart        = info->ringReadOffset + info->ringReadMapSize;   info->bufMapSize      = info->bufSize*1024*1024;   /* Reserve the rest for AGP textures */   info->gartTexStart     = info->bufStart + info->bufMapSize;   s = (info->gartSize*1024*1024 - info->gartTexStart);   l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);   if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;   info->gartTexMapSize   = (s >> l) << l;   info->log2GARTTexGran  = l;   if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize,		 DRM_AGP, DRM_READ_ONLY, &info->ringHandle) < 0) {      fprintf(stderr, "[gart] Could not add ring mapping\n");      return 0;   }   fprintf(stderr, "[gart] ring handle = 0x%08x\n", info->ringHandle);       if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize,		 DRM_AGP, DRM_READ_ONLY, &info->ringReadPtrHandle) < 0) {      fprintf(stderr,	      "[gart] Could not add ring read ptr mapping\n");      return 0;   }       fprintf(stderr, 	   "[gart] ring read ptr handle = 0x%08lx\n",	   info->ringReadPtrHandle);       if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize,		 DRM_AGP, 0, &info->bufHandle) < 0) {      fprintf(stderr,	      "[gart] Could not add vertex/indirect buffers mapping\n");      return 0;   }   fprintf(stderr, 	   "[gart] vertex/indirect buffers handle = 0x%08x\n",	   info->bufHandle);   if (drmAddMap(ctx->drmFD, info->gartTexStart, info->gartTexMapSize,		 DRM_AGP, 0, &info->gartTexHandle) < 0) {      fprintf(stderr,	      "[gart] Could not add AGP texture map mapping\n");      return 0;   }   fprintf(stderr, 	   "[gart] AGP texture map handle = 0x%08lx\n",	   info->gartTexHandle);   /* Initialize Radeon's AGP registers */   /* Ring buffer is at AGP offset 0 */   OUTREG(RADEON_AGP_BASE, info->ringHandle);   return 1;}/* Initialize the PCI GART state.  Request memory for use in PCI space, * and initialize the Radeon registers to point to that memory. */static int RADEONDRIPciInit(const DRIDriverContext *ctx, RADEONInfoPtr info){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -