コード例 #1
0
ファイル: i810_hwmc.c プロジェクト: 01org/iotg-lin-gfx-ddx
/**************************************************************************
 *
 *  I810InitMC
 *
 *  Initialize the hardware motion compensation extension for this
 *  hardware. The initialization routines want the address of the pointers
 *  to the structures, not the address of the structures. This means we
 *  allocate (or create static?) the pointer memory and pass that 
 *  address. This seems a little convoluted.
 *
 *  We need to allocate memory for the device depended adaptor record. 
 *  This is what holds the pointers to all our device functions.
 *
 *  We need to map the overlay registers into the drm.
 *
 *  We need to map the surfaces into the drm.
 *
 *  Inputs:
 *    Screen pointer
 *
 *  Outputs:
 *    None, this calls the device independent screen initialization 
 *    function.
 *
 *  Revisions:
 *  
 **************************************************************************/
void I810InitMC(ScreenPtr pScreen)
{
  ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
  I810Ptr pI810 = I810PTR(pScrn);
  int i;

  /* Clear the Surface Allocation */
  for(i=0; i<I810_MAX_SURFACES; i++) {
	pI810->surfaceAllocation[i] = 0;
  }  

  /* Cursor is at a page boundary, Overlay regs are not, don't forget */
  if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->CursorStart,
                4096, DRM_AGP, 0, (drmAddress) &pI810->overlay_map) < 0) {
    xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(overlay) failed\n");
    return;
  }
  if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->MC.Start,
                pI810->MC.Size, DRM_AGP, 0, (drmAddress) &pI810->mc_map) < 0) {
    xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(MC) failed\n");
    return;
  }
  xf86XvMCScreenInit(pScreen, 1, ppAdapt);
}
コード例 #2
0
ファイル: r128_dri.c プロジェクト: DavidGriffith/finx
/* Add a map for the MMIO registers that will be accessed by any
   DRI-based clients. */
static GLboolean R128DRIMapInit(const DRIDriverContext *ctx)
{
    R128InfoPtr info = ctx->driverPrivate;
    int flags;

    if (info->CCESecure) flags = DRM_READ_ONLY;
    else                 flags = 0;

				/* Map registers */
    if (drmAddMap(ctx->drmFD, ctx->MMIOStart, ctx->MMIOSize,
		  DRM_REGISTERS, flags, &info->registerHandle) < 0) {
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[drm] register handle = 0x%08x\n", info->registerHandle);

    return GL_TRUE;
}
コード例 #3
0
ファイル: i810_dri.c プロジェクト: 01org/iotg-lin-gfx-ddx
Bool
I810DRIScreenInit(ScreenPtr pScreen)
{
   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
   I810Ptr pI810 = I810PTR(pScrn);
   DRIInfoPtr pDRIInfo;
   I810DRIPtr pI810DRI;
   unsigned long tom;
   drm_handle_t agpHandle;
   drm_handle_t dcacheHandle;
   int sysmem_size = 0;
   int back_size = 0;
   unsigned int pitch_idx = 0;
   int bufs;
   int width = pScrn->displayWidth * pI810->cpp;
   int i;

   /* Hardware 3D rendering only implemented for 16bpp */
   /* And it only works for 5:6:5 (Mark) */
   if (pScrn->depth != 16)
      return FALSE;

   /* Check that the DRI, and DRM modules have been loaded by testing
    * for known symbols in each module. */
   if (!xf86LoaderCheckSymbol("drmAvailable"))
      return FALSE;
   if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[dri] I810DRIScreenInit failed (libdri.a too old)\n");
      return FALSE;
   }

   /* adjust width first */
#define Elements(x) sizeof(x)/sizeof(*x)
   for (pitch_idx = 0; pitch_idx < Elements(i810_pitches); pitch_idx++)
      if (width <= i810_pitches[pitch_idx])
	 break;

   if (pitch_idx == Elements(i810_pitches)) {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[dri] Couldn't find depth/back buffer pitch");
      DRICloseScreen(pScreen);
      return FALSE;
   } else {
      /* for tiled memory to work, the buffer needs to have the
       * number of lines as a multiple of 16 (the tile size),
       *  - airlied */
      int lines = (pScrn->virtualY + 15) / 16 * 16;
      back_size = i810_pitches[pitch_idx] * lines;
      back_size = ((back_size + 4096 - 1) / 4096) * 4096;
   }

   pScrn->displayWidth = i810_pitches[pitch_idx] / pI810->cpp;

   /* Check the DRI version */
   {
      int major, minor, patch;

      DRIQueryVersion(&major, &minor, &patch);
      if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
	 xf86DrvMsg(pScreen->myNum, X_ERROR,
		    "[dri] I810DRIScreenInit failed because of a version mismatch.\n"
		    "[dri] libdri version is %d.%d.%d bug version %d.%d.x is needed.\n"
		    "[dri] Disabling DRI.\n", major, minor, patch,
                    DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
	 return FALSE;
      }
   }

   pDRIInfo = DRICreateInfoRec();
   if (!pDRIInfo) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[dri] DRICreateInfoRec failed.  Disabling DRI.\n");
      return FALSE;
   }

/*     pDRIInfo->wrap.ValidateTree = 0;    */
/*     pDRIInfo->wrap.PostValidateTree = 0;    */

   pI810->pDRIInfo = pDRIInfo;
   pI810->LockHeld = 0;

   pDRIInfo->drmDriverName = I810KernelDriverName;
   pDRIInfo->clientDriverName = I810ClientDriverName;
   if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
      pDRIInfo->busIdString = DRICreatePCIBusID(pI810->PciInfo);
   } else {
      pDRIInfo->busIdString = malloc(64);
      if (pDRIInfo->busIdString)
	 sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
		 ((pI810->PciInfo->domain << 8) | pI810->PciInfo->bus),
		 pI810->PciInfo->dev, pI810->PciInfo->func
		);
   }
   if (!pDRIInfo->busIdString) {
      DRIDestroyInfoRec(pI810->pDRIInfo);
      pI810->pDRIInfo = NULL;
      return FALSE;
   }
   pDRIInfo->ddxDriverMajorVersion = I810_MAJOR_VERSION;
   pDRIInfo->ddxDriverMinorVersion = I810_MINOR_VERSION;
   pDRIInfo->ddxDriverPatchVersion = I810_PATCHLEVEL;
   pDRIInfo->frameBufferPhysicalAddress = (pointer) pI810->LinearAddr;
   pDRIInfo->frameBufferSize = (((pScrn->displayWidth *
				  pScrn->virtualY * pI810->cpp) +
				 4096 - 1) / 4096) * 4096;

   pDRIInfo->frameBufferStride = pScrn->displayWidth * pI810->cpp;
   pDRIInfo->ddxDrawableTableEntry = I810_MAX_DRAWABLES;

   if (SAREA_MAX_DRAWABLES < I810_MAX_DRAWABLES)
      pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
   else
      pDRIInfo->maxDrawableTableEntry = I810_MAX_DRAWABLES;

   /* For now the mapping works by using a fixed size defined
    * in the SAREA header
    */
   if (sizeof(XF86DRISAREARec) + sizeof(I810SAREARec) > SAREA_MAX) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[dri] Data does not fit in SAREA\n");
      return FALSE;
   }
   pDRIInfo->SAREASize = SAREA_MAX;

   if (!(pI810DRI = (I810DRIPtr) calloc(sizeof(I810DRIRec), 1))) {
      DRIDestroyInfoRec(pI810->pDRIInfo);
      pI810->pDRIInfo = NULL;
      return FALSE;
   }
   pDRIInfo->devPrivate = pI810DRI;
   pDRIInfo->devPrivateSize = sizeof(I810DRIRec);
   pDRIInfo->contextSize = sizeof(I810DRIContextRec);

   pDRIInfo->CreateContext = I810CreateContext;
   pDRIInfo->DestroyContext = I810DestroyContext;
   pDRIInfo->SwapContext = I810DRISwapContext;
   pDRIInfo->InitBuffers = I810DRIInitBuffers;
   pDRIInfo->MoveBuffers = I810DRIMoveBuffers;
   pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
   pDRIInfo->TransitionTo2d = I810DRITransitionTo2d;
   pDRIInfo->TransitionTo3d = I810DRITransitionTo3d;
   pDRIInfo->TransitionSingleToMulti3D = I810DRITransitionSingleToMulti3d;
   pDRIInfo->TransitionMultiToSingle3D = I810DRITransitionMultiToSingle3d;

   pDRIInfo->createDummyCtx = TRUE;
   pDRIInfo->createDummyCtxPriv = FALSE;

   /* This adds the framebuffer as a drm map *before* we have asked agp
    * to allocate it.  Scary stuff, hold on...
    */
   if (!DRIScreenInit(pScreen, pDRIInfo, &pI810->drmSubFD)) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[dri] DRIScreenInit failed.  Disabling DRI.\n");
      free(pDRIInfo->devPrivate);
      pDRIInfo->devPrivate = NULL;
      DRIDestroyInfoRec(pI810->pDRIInfo);
      pI810->pDRIInfo = NULL;
      return FALSE;
   }

   /* Check the i810 DRM versioning */
   {
      drmVersionPtr version;

      /* Check the DRM lib version.
       * drmGetLibVersion was not supported in version 1.0, so check for
       * symbol first to avoid possible crash or hang.
       */
      if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
	 version = drmGetLibVersion(pI810->drmSubFD);
      } else
      {
	 /* drmlib version 1.0.0 didn't have the drmGetLibVersion
	  * entry point.  Fake it by allocating a version record
	  * via drmGetVersion and changing it to version 1.0.0
	  */
	 version = drmGetVersion(pI810->drmSubFD);
	 version->version_major = 1;
	 version->version_minor = 0;
	 version->version_patchlevel = 0;
      }

#define REQ_MAJ 1
#define REQ_MIN 1
      if (version) {
	 if (version->version_major != REQ_MAJ ||
	     version->version_minor < REQ_MIN) {
	    /* incompatible drm library version */
	    xf86DrvMsg(pScreen->myNum, X_ERROR,
		       "[dri] I810DRIScreenInit failed because of a version mismatch.\n"
		       "[dri] libdrm.a module version is %d.%d.%d but version %d.%d.x is needed.\n"
		       "[dri] Disabling DRI.\n",
		       version->version_major,
		       version->version_minor, version->version_patchlevel,
		       REQ_MAJ, REQ_MIN);
	    drmFreeVersion(version);
	    I810DRICloseScreen(pScreen);
	    return FALSE;
	 }
	 drmFreeVersion(version);
      }

      /* Check the i810 DRM version */
      version = drmGetVersion(pI810->drmSubFD);
      if (version) {
	i810_drm_version = (version->version_major<<16) |
	                    version->version_minor;
	 if (version->version_major != 1 || version->version_minor < 2) {
	    /* incompatible drm version */
	    xf86DrvMsg(pScreen->myNum, X_ERROR,
		       "[dri] I810DRIScreenInit failed because of a version mismatch.\n"
		       "[dri] i810.o kernel module version is %d.%d.%d but version 1.2.0 or greater is needed.\n"
		       "[dri] Disabling DRI.\n",
		       version->version_major,
		       version->version_minor, version->version_patchlevel);
	    I810DRICloseScreen(pScreen);
	    drmFreeVersion(version);
	    return FALSE;
	 }
         pI810->drmMinor = version->version_minor;
	 drmFreeVersion(version);
      }
   }

   pI810DRI->regsSize = I810_REG_SIZE;
   if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->MMIOAddr,
		 pI810DRI->regsSize, DRM_REGISTERS, 0,
		 (drmAddress) &pI810DRI->regs) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }
   xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n",
	      (int)pI810DRI->regs);

   pI810->backHandle = DRM_AGP_NO_HANDLE;
   pI810->zHandle = DRM_AGP_NO_HANDLE;
   pI810->cursorHandle = DRM_AGP_NO_HANDLE;
   pI810->xvmcHandle = DRM_AGP_NO_HANDLE;
   pI810->sysmemHandle = DRM_AGP_NO_HANDLE;
   pI810->agpAcquired = FALSE;
   pI810->dcacheHandle = DRM_AGP_NO_HANDLE;

   /* Agp Support - Need this just to get the framebuffer.
    */
   if (drmAgpAcquire(pI810->drmSubFD) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpAquire failed\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }
   pI810->agpAcquired = TRUE;

   if (drmAgpEnable(pI810->drmSubFD, 0) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpEnable failed\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   memset(&pI810->DcacheMem, 0, sizeof(I810MemRange));
   memset(&pI810->BackBuffer, 0, sizeof(I810MemRange));
   memset(&pI810->DepthBuffer, 0, sizeof(I810MemRange));
   pI810->CursorPhysical = 0;
   pI810->CursorARGBPhysical = 0;

   /* Dcache - half the speed of normal ram, but has use as a Z buffer
    * under the DRI.
    */

   drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL,
	       (drmAddress) &dcacheHandle);
   pI810->dcacheHandle = dcacheHandle;

   xf86DrvMsg(pScreen->myNum, X_INFO, "[agp] dcacheHandle : 0x%x\n",
	      (int)dcacheHandle);

   sysmem_size = pScrn->videoRam * 1024;
   if (dcacheHandle != DRM_AGP_NO_HANDLE) {
      if (back_size > 4 * 1024 * 1024) {
	 xf86DrvMsg(pScreen->myNum, X_INFO,
		    "[dri] Backsize is larger then 4 meg\n");
	 sysmem_size = sysmem_size - 2 * back_size;
	 drmAgpFree(pI810->drmSubFD, dcacheHandle);
	 pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE;
      } else {
	 sysmem_size = sysmem_size - back_size;
      }
   } else {
      sysmem_size = sysmem_size - 2 * back_size;
   }

   /* Max size is 48 without XvMC, 41 with 6 surfaces, 40 with 7 surfaces */
   if (pI810->numSurfaces && (pI810->numSurfaces == 6)) {
      if (sysmem_size > (pI810->FbMapSize - 7 * 1024 * 1024)) {
	 sysmem_size = (pI810->FbMapSize - 7 * 1024 * 1024);
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "User requested more memory then fits in the agp aperture\n"
		    "Truncating to %d bytes of memory\n", sysmem_size);
      }
   }
   if (pI810->numSurfaces && (pI810->numSurfaces == 7)) {
      if (sysmem_size > (pI810->FbMapSize - 8 * 1024 * 1024)) {
	 sysmem_size = (pI810->FbMapSize - 8 * 1024 * 1024);
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "User requested more memory then fits in the agp aperture\n"
		    "Truncating to %d bytes of memory\n", sysmem_size);
      }
   }

   if (sysmem_size > pI810->FbMapSize) {
      sysmem_size = pI810->FbMapSize;

      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[dri] User requested more memory then fits in the agp"
		 " aperture\n\tTruncating to %d bytes of memory\n",
		 sysmem_size);
   }

   sysmem_size -= 4096;			/* remove 4k for the hw cursor */
   sysmem_size -= 16384;		/* remove 16k for the ARGB hw cursor */

   pI810->SysMem.Start = 0;
   pI810->SysMem.Size = sysmem_size;
   pI810->SysMem.End = sysmem_size;
   tom = sysmem_size;

   pI810->SavedSysMem = pI810->SysMem;

   if (dcacheHandle != DRM_AGP_NO_HANDLE) {
      if (drmAgpBind(pI810->drmSubFD, dcacheHandle, pI810->DepthOffset) == 0) {
	 memset(&pI810->DcacheMem, 0, sizeof(I810MemRange));
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] GART: Found 4096K Z buffer memory\n");
	 pI810->DcacheMem.Start = pI810->DepthOffset;
	 pI810->DcacheMem.Size = 1024 * 4096;
	 pI810->DcacheMem.End =
	       pI810->DcacheMem.Start + pI810->DcacheMem.Size;
	 if (!I810AllocLow
	     (&(pI810->DepthBuffer), &(pI810->DcacheMem), back_size)) {
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		       "[agp] Depth buffer allocation failed\n");
	    DRICloseScreen(pScreen);
	    return FALSE;
	 }
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] GART: dcache bind failed\n");
	 drmAgpFree(pI810->drmSubFD, dcacheHandle);
	 pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE;
      }
   } else {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[agp] GART: no dcache memory found\n");
   }

   drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL,
	       (drmAddress) &agpHandle);
   pI810->backHandle = agpHandle;

   if (agpHandle != DRM_AGP_NO_HANDLE) {
      if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->BackOffset) == 0) {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] Bound backbuffer memory\n");

	 pI810->BackBuffer.Start = pI810->BackOffset;
	 pI810->BackBuffer.Size = back_size;
	 pI810->BackBuffer.End = (pI810->BackBuffer.Start +
				  pI810->BackBuffer.Size);
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] Unable to bind backbuffer.  Disabling DRI.\n");
	 DRICloseScreen(pScreen);
	 return FALSE;
      }
   } else {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[dri] Unable to allocate backbuffer memory.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   if (dcacheHandle == DRM_AGP_NO_HANDLE) {
     drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL,
		 (drmAddress) &agpHandle);

      pI810->zHandle = agpHandle;

      if (agpHandle != DRM_AGP_NO_HANDLE) {
	 if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->DepthOffset) == 0) {
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		       "[agp] Bound depthbuffer memory\n");
	    pI810->DepthBuffer.Start = pI810->DepthOffset;
	    pI810->DepthBuffer.Size = back_size;
	    pI810->DepthBuffer.End = (pI810->DepthBuffer.Start +
				      pI810->DepthBuffer.Size);
	 } else {
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		       "[agp] Unable to bind depthbuffer.  Disabling DRI.\n");
	    DRICloseScreen(pScreen);
	    return FALSE;
	 }
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] Unable to allocate depthbuffer memory.  Disabling DRI.\n");
	 DRICloseScreen(pScreen);
	 return FALSE;
      }
   }

   /* Now allocate and bind the agp space.  This memory will include the
    * regular framebuffer as well as texture memory.
    */
   drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL,
	       (drmAddress)&agpHandle);
   pI810->sysmemHandle = agpHandle;

   if (agpHandle != DRM_AGP_NO_HANDLE) {
      if (drmAgpBind(pI810->drmSubFD, agpHandle, 0) == 0) {
	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		   "[agp] Bound System Texture Memory\n");
      } else {
          xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to bind system texture memory. Disabling DRI.\n");
	  DRICloseScreen(pScreen);
	  return FALSE;
      }
   } else {
      xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to allocate system texture memory. Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

/* Allocate 7 or 8MB for XvMC this is setup as follows to best use tiled
   regions and required surface pitches. (Numbers are adjusted if the
   AGP region is only 32MB
   For numSurfaces == 6
   44 - 48MB = 4MB Fence, 8 Tiles wide
   43 - 44MB = 1MB Fence, 8 Tiles wide
   42 - 43MB = 1MB Fence, 4 Tiles wide
   41 - 42MB = 1MB Fence, 4 Tiles wide
   For numSurfaces == 7
   44 - 48MB   = 4MB Fence, 8 Tiles wide
   43 - 44MB   = 1MB Fence, 8 Tiles wide
   42.5 - 43MB = 0.5MB Fence, 8 Tiles wide
   42 - 42.5MB = 0.5MB Fence, 4 Tiles wide
   40 - 42MB   = 2MB Fence, 4 Tiles wide
 */
   if (pI810->numSurfaces) {
      if (pI810->numSurfaces == 6) {
	 pI810->MC.Size = 7 * 1024 * 1024;
	 pI810->MC.Start = pI810->FbMapSize - 7 * 1024 * 1024;

      }
      if (pI810->numSurfaces == 7) {
	 pI810->MC.Size = 8 * 1024 * 1024;
	 pI810->MC.Start = pI810->FbMapSize - 8 * 1024 * 1024;
      }
      drmAgpAlloc(pI810->drmSubFD, pI810->MC.Size, 0, NULL,
		  (drmAddress) &agpHandle);

      pI810->xvmcHandle = agpHandle;

      if (agpHandle != DRM_AGP_NO_HANDLE) {
	 if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->MC.Start) == 0) {
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		       "GART: Allocated 7MB for HWMC\n");
	    pI810->MC.End = pI810->MC.Start + pI810->MC.Size;
	 } else {
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC bind failed\n");
	    pI810->MC.Start = 0;
	    pI810->MC.Size = 0;
	    pI810->MC.End = 0;
	 }
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC alloc failed\n");
	 pI810->MC.Start = 0;
	 pI810->MC.Size = 0;
	 pI810->MC.End = 0;
      }
      pI810->xvmcContext = 0;
   }

   drmAgpAlloc(pI810->drmSubFD, 4096, 2,
	       (unsigned long *)&pI810->CursorPhysical,
	       (drmAddress) &agpHandle);

   pI810->cursorHandle = agpHandle;

   if (agpHandle != DRM_AGP_NO_HANDLE) {
      tom = sysmem_size;

      if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] GART: Allocated 4K for mouse cursor image\n");
	 pI810->CursorStart = tom;
	 tom += 4096;
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] GART: cursor bind failed\n");
	 pI810->CursorPhysical = 0;
      }
   } else {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[agp] GART: cursor alloc failed\n");
      pI810->CursorPhysical = 0;
   }

   drmAgpAlloc(pI810->drmSubFD, 16384, 2,
	       (unsigned long *)&pI810->CursorARGBPhysical,
	       (drmAddress) &agpHandle);

   pI810->cursorARGBHandle = agpHandle;

   if (agpHandle != DRM_AGP_NO_HANDLE) {
      if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] GART: Allocated 16K for ARGB mouse cursor image\n");
	 pI810->CursorARGBStart = tom;
	 tom += 16384;
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] GART: ARGB cursor bind failed\n");
	 pI810->CursorARGBPhysical = 0;
      }
   } else {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[agp] GART: ARGB cursor alloc failed\n");
      pI810->CursorARGBPhysical = 0;
   }

   /* Steal some of the excess cursor space for the overlay regs.
    */
   pI810->OverlayPhysical = pI810->CursorPhysical + 1024;
   pI810->OverlayStart = pI810->CursorStart + 1024;

   I810SetTiledMemory(pScrn, 1,
		      pI810->DepthBuffer.Start,
		      i810_pitches[pitch_idx], 8 * 1024 * 1024);

   I810SetTiledMemory(pScrn, 2,
		      pI810->BackBuffer.Start,
		      i810_pitches[pitch_idx], 8 * 1024 * 1024);

   /* These are for HWMC surfaces */
   if (pI810->numSurfaces == 6) {
      I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 1024 * 1024);

      I810SetTiledMemory(pScrn, 4,
			 pI810->MC.Start + 1024 * 1024, 512, 1024 * 1024);

      I810SetTiledMemory(pScrn, 5,
			 pI810->MC.Start + 1024 * 1024 * 2,
			 1024, 1024 * 1024);

      I810SetTiledMemory(pScrn, 6,
			 pI810->MC.Start + 1024 * 1024 * 3,
			 1024, 4 * 1024 * 1024);
   }
   if (pI810->numSurfaces == 7) {
      I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 2 * 1024 * 1024);

      I810SetTiledMemory(pScrn, 4,
			 pI810->MC.Start + 2 * 1024 * 1024, 512, 512 * 1024);

      I810SetTiledMemory(pScrn, 5,
			 pI810->MC.Start + 2 * 1024 * 1024 + 512 * 1024,
			 1024, 512 * 1024);

      I810SetTiledMemory(pScrn, 6,
			 pI810->MC.Start + 3 * 1024 * 1024,
			 1024, 1 * 1024 * 1024);

      I810SetTiledMemory(pScrn, 7,
			 pI810->MC.Start + 4 * 1024 * 1024,
			 1024, 4 * 1024 * 1024);

   }

   pI810->auxPitch = i810_pitches[pitch_idx];
   pI810->auxPitchBits = i810_pitch_flags[pitch_idx];
   pI810->SavedDcacheMem = pI810->DcacheMem;
   pI810DRI->backbufferSize = pI810->BackBuffer.Size;

   if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BackBuffer.Start,
		 pI810->BackBuffer.Size, DRM_AGP, 0,
		 (drmAddress) &pI810DRI->backbuffer) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[drm] drmAddMap(backbuffer) failed.  Disabling DRI\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   pI810DRI->depthbufferSize = pI810->DepthBuffer.Size;
   if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->DepthBuffer.Start,
		 pI810->DepthBuffer.Size, DRM_AGP, 0,
		 (drmAddress) &pI810DRI->depthbuffer) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[drm] drmAddMap(depthbuffer) failed.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   /* Allocate FrontBuffer etc. */
   if (!I810AllocateFront(pScrn)) {
      DRICloseScreen(pScreen);
      return FALSE;
   }

   /* Allocate buffer memory */
   I810AllocHigh(&(pI810->BufferMem), &(pI810->SysMem),
		 I810_DMA_BUF_NR * I810_DMA_BUF_SZ);

   xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] Buffer map : %lx\n",
	      pI810->BufferMem.Start);

   if (pI810->BufferMem.Start == 0 ||
       pI810->BufferMem.End - pI810->BufferMem.Start >
       I810_DMA_BUF_NR * I810_DMA_BUF_SZ) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[dri] Not enough memory for dma buffers.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }
   if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BufferMem.Start,
		 pI810->BufferMem.Size, DRM_AGP, 0,
		 (drmAddress) &pI810->buffer_map) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[drm] drmAddMap(buffer_map) failed.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   pI810DRI->agp_buffers = pI810->buffer_map;
   pI810DRI->agp_buf_size = pI810->BufferMem.Size;

   if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->LpRing->mem.Start,
		 pI810->LpRing->mem.Size, DRM_AGP, 0,
		 (drmAddress) &pI810->ring_map) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[drm] drmAddMap(ring_map) failed.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   /* Use the rest of memory for textures. */
   pI810DRI->textureSize = pI810->SysMem.Size;

   i = mylog2(pI810DRI->textureSize / I810_NR_TEX_REGIONS);

   if (i < I810_LOG_MIN_TEX_REGION_SIZE)
      i = I810_LOG_MIN_TEX_REGION_SIZE;

   pI810DRI->logTextureGranularity = i;
   pI810DRI->textureSize = (pI810DRI->textureSize >> i) << i;	/* truncate */

   if (pI810DRI->textureSize < 512 * 1024) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[drm] Less then 512k memory left for textures.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   if (!I810AllocLow(&(pI810->TexMem), &(pI810->SysMem), pI810DRI->textureSize)) {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[agp] Texure memory allocation failed\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->TexMem.Start,
		 pI810->TexMem.Size, DRM_AGP, 0,
		 (drmAddress) &pI810DRI->textures) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[drm] drmAddMap(textures) failed.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   if ((bufs = drmAddBufs(pI810->drmSubFD,
			  I810_DMA_BUF_NR,
			  I810_DMA_BUF_SZ,
			  DRM_AGP_BUFFER, pI810->BufferMem.Start)) <= 0) {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[drm] failure adding %d %d byte DMA buffers.  Disabling DRI.\n",
		 I810_DMA_BUF_NR, I810_DMA_BUF_SZ);
      DRICloseScreen(pScreen);
      return FALSE;
   }

   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
	      "[drm] added %d %d byte DMA buffers\n", bufs, I810_DMA_BUF_SZ);

   I810InitDma(pScrn);

   /* Okay now initialize the dma engine */

   if (!pI810DRI->irq) {
      pI810DRI->irq = drmGetInterruptFromBusID(pI810->drmSubFD,
					       ((pI810->PciInfo->domain << 8) |
						pI810->PciInfo->bus),
					       pI810->PciInfo->dev,
					       pI810->PciInfo->func
					       );
      if ((drmCtlInstHandler(pI810->drmSubFD, pI810DRI->irq)) != 0) {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[drm] failure adding irq handler, there is a device "
		    "already using that irq\n Consider rearranging your "
		    "PCI cards.  Disabling DRI.\n");
	 DRICloseScreen(pScreen);
	 return FALSE;
      }
   }

   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
	      "[drm] dma control initialized, using IRQ %d\n", pI810DRI->irq);

   pI810DRI->deviceID = pI810->PciInfo->device_id;
   pI810DRI->width = pScrn->virtualX;
   pI810DRI->height = pScrn->virtualY;
   pI810DRI->mem = pScrn->videoRam * 1024;
   pI810DRI->cpp = pI810->cpp;

   pI810DRI->fbOffset = pI810->FrontBuffer.Start;
   pI810DRI->fbStride = pI810->auxPitch;

   pI810DRI->bitsPerPixel = pScrn->bitsPerPixel;

   pI810DRI->textureOffset = pI810->TexMem.Start;

   pI810DRI->backOffset = pI810->BackBuffer.Start;
   pI810DRI->depthOffset = pI810->DepthBuffer.Start;

   pI810DRI->ringOffset = pI810->LpRing->mem.Start;
   pI810DRI->ringSize = pI810->LpRing->mem.Size;

   pI810DRI->auxPitch = pI810->auxPitch;
   pI810DRI->auxPitchBits = pI810->auxPitchBits;
   pI810DRI->sarea_priv_offset = sizeof(XF86DRISAREARec);

   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
	      "[dri] visual configs initialized.\n");
   pI810->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;

   return TRUE;
}
void
ViaInitXVMC(ScreenPtr pScreen)
{
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    VIAPtr pVia = VIAPTR(pScrn);
    ViaXvMCPtr vXvMC = &(pVia->xvmc);
    volatile ViaXvMCSAreaPriv *saPriv;

    pVia->XvMCEnabled = 0;

    if ((pVia->Chipset == VIA_KM400) ||
        (pVia->Chipset == VIA_CX700) ||
        (pVia->Chipset == VIA_K8M890) ||
        (pVia->Chipset == VIA_P4M900) ||
        (pVia->Chipset == VIA_VX800) ||
        (pVia->Chipset == VIA_VX855) ||
        (pVia->Chipset == VIA_VX900)) {
        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                   "[XvMC] XvMC is not supported on this chipset.\n");
        return;
    }

    if (!pVia->directRenderingType) {
        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                   "[XvMC] Cannot use XvMC without DRI!\n");
        return;
    }

    if (((pVia->drmVerMajor <= 2) && (pVia->drmVerMinor < 4))) {
        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                   "[XvMC] Kernel drm is not compatible with XvMC.\n");
        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                   "[XvMC] Kernel drm version is %d.%d.%d; "
                   "at least version 2.4.0 is needed.\n",
                   pVia->drmVerMajor, pVia->drmVerMinor, pVia->drmVerPL);
        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                   "[XvMC] Please update. Disabling XvMC.\n");
        return;
    }

    vXvMC->mmioBase = pVia->registerHandle;

    if (drmAddMap(pVia->drmmode.fd,
                  (drm_handle_t) pVia->FrameBufferBase,
                  pVia->videoRambytes, DRM_FRAME_BUFFER, 0,
                  &(vXvMC->fbBase)) < 0) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                   "[XvMC] drmAddMap(FB) failed. Disabling XvMC.\n");
        return;
    }

    initViaXvMC(vXvMC);

    if (!xf86XvMCScreenInit(pScreen, 1, ((pVia->Chipset == VIA_PM800)
                                         ? ppAdapt_pga : ppAdapt))) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                   "[XvMC] XvMCScreenInit failed. Disabling XvMC.\n");
        drmRmMap(pVia->drmmode.fd, vXvMC->fbBase);
        return;
    }
#if (XvMCVersion > 1) || (XvMCRevision > 0)
    {
        DRIInfoPtr pDRIInfo = pVia->pDRIInfo;

        if (pVia->ChipId != PCI_CHIP_VT3259 &&
            pVia->ChipId != PCI_CHIP_VT3364) {
            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                       "[XvMC] Registering chromeXvMC.\n");
            xf86XvMCRegisterDRInfo(pScreen, "chromeXvMC", pDRIInfo->busIdString,
                                   VIAXVMC_MAJOR, VIAXVMC_MINOR, VIAXVMC_PL);
        } else {
            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                       "[XvMC] Registering chromeXvMCPro.\n");
            xf86XvMCRegisterDRInfo(pScreen, "chromeXvMCPro",
                                   pDRIInfo->busIdString, VIAXVMC_MAJOR,
                                   VIAXVMC_MINOR, VIAXVMC_PL);
        }
    }
#endif

    vXvMC->activePorts = 0;
    saPriv = (ViaXvMCSAreaPriv *) DRIGetSAREAPrivate(pScreen);
    saPriv->XvMCCtxNoGrabbed = ~0;

    XVMCLOCKPTR(saPriv, UNICHROME_LOCK_DECODER1)->lock = 0;

    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
               "[XvMC] Initialized XvMC extension.\n");
    pVia->XvMCEnabled = 1;
}
コード例 #5
0
ファイル: r128_dri.c プロジェクト: DavidGriffith/finx
/* Initialize the AGP state.  Request memory for use in AGP space, and
   initialize the Rage 128 registers to point to that memory. */
static GLboolean R128DRIAgpInit(const DRIDriverContext *ctx)
{
    unsigned char *R128MMIO = ctx->MMIOAddress;
    R128InfoPtr info = ctx->driverPrivate;
    unsigned long mode;
    unsigned int  vendor, device;
    int           ret;
    unsigned long cntl, chunk;
    int           s, l;
    int           flags;
    unsigned long agpBase;

    if (drmAgpAcquire(ctx->drmFD) < 0) {
	fprintf(stderr, "[agp] AGP not available\n");
	return GL_FALSE;
    }

				/* 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 */
    vendor = drmAgpVendorId(ctx->drmFD);
    device = drmAgpDeviceId(ctx->drmFD);

    mode &= ~R128_AGP_MODE_MASK;
    switch (info->agpMode) {
    case 4:          mode |= R128_AGP_4X_MODE;
    case 2:          mode |= R128_AGP_2X_MODE;
    case 1: default: mode |= R128_AGP_1X_MODE;
    }

    fprintf(stderr,
	       "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
	       mode, vendor, device,
	       0x1002,
	       info->Chipset);

    if (drmAgpEnable(ctx->drmFD, mode) < 0) {
	fprintf(stderr, "[agp] AGP not enabled\n");
	drmAgpRelease(ctx->drmFD);
	return GL_FALSE;
    }

    info->agpOffset = 0;

    if ((ret = drmAgpAlloc(ctx->drmFD, info->agpSize*1024*1024, 0, NULL,
			   &info->agpMemHandle)) < 0) {
	fprintf(stderr, "[agp] Out of memory (%d)\n", ret);
	drmAgpRelease(ctx->drmFD);
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[agp] %d kB allocated with handle 0x%08x\n",
	       info->agpSize*1024, info->agpMemHandle);

    if (drmAgpBind(ctx->drmFD, info->agpMemHandle, info->agpOffset) < 0) {
	fprintf(stderr, "[agp] Could not bind\n");
	drmAgpFree(ctx->drmFD, info->agpMemHandle);
	drmAgpRelease(ctx->drmFD);
	return GL_FALSE;
    }

				/* Initialize the CCE ring buffer data */
    info->ringStart       = info->agpOffset;
    info->ringMapSize     = info->ringSize*1024*1024 + r128_drm_page_size;
    info->ringSizeLog2QW  = R128MinBits(info->ringSize*1024*1024/8) - 1;

    info->ringReadOffset  = info->ringStart + info->ringMapSize;
    info->ringReadMapSize = r128_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->agpTexStart     = info->bufStart + info->bufMapSize;
    s = (info->agpSize*1024*1024 - info->agpTexStart);
    l = R128MinBits((s-1) / R128_NR_TEX_REGIONS);
    if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY;
    info->agpTexMapSize   = (s >> l) << l;
    info->log2AGPTexGran  = l;

    if (info->CCESecure) flags = DRM_READ_ONLY;
    else                  flags = 0;

    if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize,
		  DRM_AGP, flags, &info->ringHandle) < 0) {
	fprintf(stderr,
		   "[agp] Could not add ring mapping\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[agp] ring handle = 0x%08x\n", info->ringHandle);

    if (drmMap(ctx->drmFD, info->ringHandle, info->ringMapSize,
	       (drmAddressPtr)&info->ring) < 0) {
	fprintf(stderr, "[agp] Could not map ring\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[agp] Ring mapped at 0x%08lx\n",
	       (unsigned long)info->ring);

    if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize,
		  DRM_AGP, flags, &info->ringReadPtrHandle) < 0) {
	fprintf(stderr,
		   "[agp] Could not add ring read ptr mapping\n");
	return GL_FALSE;
    }
    fprintf(stderr,
 	       "[agp] ring read ptr handle = 0x%08x\n",
	       info->ringReadPtrHandle);

    if (drmMap(ctx->drmFD, info->ringReadPtrHandle, info->ringReadMapSize,
	       (drmAddressPtr)&info->ringReadPtr) < 0) {
	fprintf(stderr,
		   "[agp] Could not map ring read ptr\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[agp] Ring read ptr mapped at 0x%08lx\n",
	       (unsigned long)info->ringReadPtr);

    if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize,
		  DRM_AGP, 0, &info->bufHandle) < 0) {
	fprintf(stderr,
		   "[agp] Could not add vertex/indirect buffers mapping\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[agp] vertex/indirect buffers handle = 0x%08lx\n",
	       info->bufHandle);

    if (drmMap(ctx->drmFD, info->bufHandle, info->bufMapSize,
	       (drmAddressPtr)&info->buf) < 0) {
	fprintf(stderr,
		   "[agp] Could not map vertex/indirect buffers\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[agp] Vertex/indirect buffers mapped at 0x%08lx\n",
	       (unsigned long)info->buf);

    if (drmAddMap(ctx->drmFD, info->agpTexStart, info->agpTexMapSize,
		  DRM_AGP, 0, &info->agpTexHandle) < 0) {
	fprintf(stderr,
		   "[agp] Could not add AGP texture map mapping\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[agp] AGP texture map handle = 0x%08lx\n",
	       info->agpTexHandle);

    if (drmMap(ctx->drmFD, info->agpTexHandle, info->agpTexMapSize,
	       (drmAddressPtr)&info->agpTex) < 0) {
	fprintf(stderr,
		   "[agp] Could not map AGP texture map\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[agp] AGP Texture map mapped at 0x%08lx\n",
	       (unsigned long)info->agpTex);

				/* Initialize Rage 128's AGP registers */
    cntl  = INREG(R128_AGP_CNTL);
    cntl &= ~R128_AGP_APER_SIZE_MASK;
    switch (info->agpSize) {
    case 256: cntl |= R128_AGP_APER_SIZE_256MB; break;
    case 128: cntl |= R128_AGP_APER_SIZE_128MB; break;
    case  64: cntl |= R128_AGP_APER_SIZE_64MB;  break;
    case  32: cntl |= R128_AGP_APER_SIZE_32MB;  break;
    case  16: cntl |= R128_AGP_APER_SIZE_16MB;  break;
    case   8: cntl |= R128_AGP_APER_SIZE_8MB;   break;
    case   4: cntl |= R128_AGP_APER_SIZE_4MB;   break;
    default:
	fprintf(stderr,
		   "[agp] Illegal aperture size %d kB\n",
		   info->agpSize*1024);
	return GL_FALSE;
    }
    agpBase = drmAgpBase(ctx->drmFD);
    OUTREG(R128_AGP_BASE, agpBase); 
    OUTREG(R128_AGP_CNTL, cntl);

				/* Disable Rage 128's PCIGART registers */
    chunk = INREG(R128_BM_CHUNK_0_VAL);
    chunk &= ~(R128_BM_PTR_FORCE_TO_PCI |
	       R128_BM_PM4_RD_FORCE_TO_PCI |
	       R128_BM_GLOBAL_FORCE_TO_PCI);
    OUTREG(R128_BM_CHUNK_0_VAL, chunk);

    OUTREG(R128_PCI_GART_PAGE, 1); /* Ensure AGP GART is used (for now) */

    return GL_TRUE;
}
コード例 #6
0
ファイル: r128_dri.c プロジェクト: DavidGriffith/finx
/* Initialize the screen-specific data structures for the DRI and the
   Rage 128.  This is the main entry point to the device-specific
   initialization code.  It calls device-independent DRI functions to
   create the DRI data structures and initialize the DRI state. */
static GLboolean R128DRIScreenInit(DRIDriverContext *ctx)
{
    R128InfoPtr info = ctx->driverPrivate;
    R128DRIPtr    pR128DRI;
    int           err, major, minor, patch;
    drmVersionPtr version;
    drm_r128_sarea_t *pSAREAPriv;

    switch (ctx->bpp) {
    case 8:
	/* These modes are not supported (yet). */
    case 15:
    case 24:
	fprintf(stderr,
		   "[dri] R128DRIScreenInit failed (depth %d not supported).  "
		   "[dri] Disabling DRI.\n", ctx->bpp);
	return GL_FALSE;

	/* Only 16 and 32 color depths are supports currently. */
    case 16:
    case 32:
	break;
    }
    r128_drm_page_size = getpagesize();
    
    info->registerSize = ctx->MMIOSize;
    ctx->shared.SAREASize = SAREA_MAX;

    /* Note that drmOpen will try to load the kernel module, if needed. */
    ctx->drmFD = drmOpen("r128", NULL );
    if (ctx->drmFD < 0) {
	fprintf(stderr, "[drm] drmOpen failed\n");
	return 0;
    }
    
    /* Check the r128 DRM version */
    version = drmGetVersion(ctx->drmFD);
    if (version) {
	if (version->version_major != 2 ||
	    version->version_minor < 2) {
	    /* incompatible drm version */
	    fprintf(stderr,
		"[dri] R128DRIScreenInit failed because of a version mismatch.\n"
		"[dri] r128.o kernel module version is %d.%d.%d but version 2.2 or greater is needed.\n"
		"[dri] Disabling the DRI.\n",
		version->version_major,
		version->version_minor,
		version->version_patchlevel);
	    drmFreeVersion(version);
	    return GL_FALSE;
	}
	info->drmMinor = version->version_minor;
	drmFreeVersion(version);
    }
    
    if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) {
	fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
		ctx->drmFD, ctx->pciBusID, strerror(-err));
	return 0;
    }
    
   if (drmAddMap( ctx->drmFD,
		  0,
		  ctx->shared.SAREASize,
		  DRM_SHM,
		  DRM_CONTAINS_LOCK,
		  &ctx->shared.hSAREA) < 0)
   {
      fprintf(stderr, "[drm] drmAddMap failed\n");
      return 0;
   }
   fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n",
	   ctx->shared.SAREASize, ctx->shared.hSAREA);

   if (drmMap( ctx->drmFD,
	       ctx->shared.hSAREA,
	       ctx->shared.SAREASize,
	       (drmAddressPtr)(&ctx->pSAREA)) < 0)
   {
      fprintf(stderr, "[drm] drmMap failed\n");
      return 0;
   }
   memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
   fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
	   ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
   
   /* Need to AddMap the framebuffer and mmio regions here:
    */
   if (drmAddMap( ctx->drmFD,
		  (drm_handle_t)ctx->FBStart,
		  ctx->FBSize,
		  DRM_FRAME_BUFFER,
		  0,
		  &ctx->shared.hFrameBuffer) < 0)
   {
      fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
      return 0;
   }

   fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
	   ctx->shared.hFrameBuffer);

   if (!R128MemoryInit(ctx))
	return GL_FALSE;
   
				/* Initialize AGP */
    if (!info->IsPCI && !R128DRIAgpInit(ctx)) {
	info->IsPCI = GL_TRUE;
	fprintf(stderr,
		   "[agp] AGP failed to initialize -- falling back to PCI mode.\n");
	fprintf(stderr,
		   "[agp] Make sure you have the agpgart kernel module loaded.\n");
    }

				/* Initialize PCIGART */
    if (info->IsPCI && !R128DRIPciInit(ctx)) {
	return GL_FALSE;
    }

				/* DRIScreenInit doesn't add all the
				   common mappings.  Add additional
				   mappings here. */
    if (!R128DRIMapInit(ctx)) {
	return GL_FALSE;
    }

   /* Create a 'server' context so we can grab the lock for
    * initialization ioctls.
    */
   if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) {
      fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
      return 0;
   }

   DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); 

    /* Initialize the kernel data structures */
    if (!R128DRIKernelInit(ctx)) {
	return GL_FALSE;
    }

    /* Initialize the vertex buffers list */
    if (!R128DRIBufInit(ctx)) {
	return GL_FALSE;
    }

    /* Initialize IRQ */
    R128DRIIrqInit(ctx);

    /* Initialize and start the CCE if required */
    R128DRICCEInit(ctx);

   /* Quick hack to clear the front & back buffers.  Could also use
    * the clear ioctl to do this, but would need to setup hw state
    * first.
    */
   drimemsetio((char *)ctx->FBAddress + info->frontOffset,
	  0,
	  info->frontPitch * ctx->cpp * ctx->shared.virtualHeight );

   drimemsetio((char *)ctx->FBAddress + info->backOffset,
	  0,
	  info->backPitch * ctx->cpp * ctx->shared.virtualHeight );
    
    pSAREAPriv = (drm_r128_sarea_t *)(((char*)ctx->pSAREA) + 
					sizeof(drm_sarea_t));
    memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));

   /* This is the struct passed to radeon_dri.so for its initialization */
   ctx->driverClientMsg = malloc(sizeof(R128DRIRec));
   ctx->driverClientMsgSize = sizeof(R128DRIRec);
   
    pR128DRI                    = (R128DRIPtr)ctx->driverClientMsg;
    pR128DRI->deviceID          = info->Chipset;
    pR128DRI->width             = ctx->shared.virtualWidth;
    pR128DRI->height            = ctx->shared.virtualHeight;
    pR128DRI->depth             = ctx->bpp;
    pR128DRI->bpp               = ctx->bpp;

    pR128DRI->IsPCI             = info->IsPCI;
    pR128DRI->AGPMode           = info->agpMode;

    pR128DRI->frontOffset       = info->frontOffset;
    pR128DRI->frontPitch        = info->frontPitch;
    pR128DRI->backOffset        = info->backOffset;
    pR128DRI->backPitch         = info->backPitch;
    pR128DRI->depthOffset       = info->depthOffset;
    pR128DRI->depthPitch        = info->depthPitch;
    pR128DRI->spanOffset        = info->spanOffset;
    pR128DRI->textureOffset     = info->textureOffset;
    pR128DRI->textureSize       = info->textureSize;
    pR128DRI->log2TexGran       = info->log2TexGran;

    pR128DRI->registerHandle    = info->registerHandle;
    pR128DRI->registerSize      = info->registerSize;

    pR128DRI->agpTexHandle      = info->agpTexHandle;
    pR128DRI->agpTexMapSize     = info->agpTexMapSize;
    pR128DRI->log2AGPTexGran    = info->log2AGPTexGran;
    pR128DRI->agpTexOffset      = info->agpTexStart;
    pR128DRI->sarea_priv_offset = sizeof(drm_sarea_t);

    return GL_TRUE;
}
コード例 #7
0
ファイル: r128_dri.c プロジェクト: DavidGriffith/finx
static GLboolean R128DRIPciInit(const DRIDriverContext *ctx)
{
    R128InfoPtr info = ctx->driverPrivate;
    unsigned char *R128MMIO = ctx->MMIOAddress;
    u_int32_t chunk;
    int ret;
    int flags;

    info->agpOffset = 0;

    ret = drmScatterGatherAlloc(ctx->drmFD, info->agpSize*1024*1024,
				&info->pciMemHandle);
    if (ret < 0) {
	fprintf(stderr, "[pci] Out of memory (%d)\n", ret);
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[pci] %d kB allocated with handle 0x%08x\n",
	       info->agpSize*1024, info->pciMemHandle);

				/* Initialize the CCE ring buffer data */
    info->ringStart       = info->agpOffset;
    info->ringMapSize     = info->ringSize*1024*1024 + r128_drm_page_size;
    info->ringSizeLog2QW  = R128MinBits(info->ringSize*1024*1024/8) - 1;

    info->ringReadOffset  = info->ringStart + info->ringMapSize;
    info->ringReadMapSize = r128_drm_page_size;

				/* Reserve space for vertex/indirect buffers */
    info->bufStart        = info->ringReadOffset + info->ringReadMapSize;
    info->bufMapSize      = info->bufSize*1024*1024;

    flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL;

    if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize,
		  DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) {
	fprintf(stderr,
		   "[pci] Could not add ring mapping\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[pci] ring handle = 0x%08lx\n", info->ringHandle);

    if (drmMap(ctx->drmFD, info->ringHandle, info->ringMapSize,
	       (drmAddressPtr)&info->ring) < 0) {
	fprintf(stderr, "[pci] Could not map ring\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[pci] Ring mapped at 0x%08lx\n",
	       (unsigned long)info->ring);
    fprintf(stderr,
	       "[pci] Ring contents 0x%08lx\n",
	       *(unsigned long *)info->ring);

    if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize,
		  DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) {
	fprintf(stderr,
		   "[pci] Could not add ring read ptr mapping\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[pci] ring read ptr handle = 0x%08lx\n",
	       info->ringReadPtrHandle);

    if (drmMap(ctx->drmFD, info->ringReadPtrHandle, info->ringReadMapSize,
	       (drmAddressPtr)&info->ringReadPtr) < 0) {
	fprintf(stderr,
		   "[pci] Could not map ring read ptr\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[pci] Ring read ptr mapped at 0x%08lx\n",
	       (unsigned long)info->ringReadPtr);
    fprintf(stderr,
	       "[pci] Ring read ptr contents 0x%08lx\n",
	       *(unsigned long *)info->ringReadPtr);

    if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize,
		  DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) {
	fprintf(stderr,
		   "[pci] Could not add vertex/indirect buffers mapping\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[pci] vertex/indirect buffers handle = 0x%08lx\n",
	       info->bufHandle);

    if (drmMap(ctx->drmFD, info->bufHandle, info->bufMapSize,
	       (drmAddressPtr)&info->buf) < 0) {
	fprintf(stderr,
		   "[pci] Could not map vertex/indirect buffers\n");
	return GL_FALSE;
    }
    fprintf(stderr,
	       "[pci] Vertex/indirect buffers mapped at 0x%08lx\n",
	       (unsigned long)info->buf);
    fprintf(stderr,
	       "[pci] Vertex/indirect buffers contents 0x%08lx\n",
	       *(unsigned long *)info->buf);

    if (!info->IsPCI) {
	/* This is really an AGP card, force PCI GART mode */
        chunk = INREG(R128_BM_CHUNK_0_VAL);
        chunk |= (R128_BM_PTR_FORCE_TO_PCI |
		  R128_BM_PM4_RD_FORCE_TO_PCI |
		  R128_BM_GLOBAL_FORCE_TO_PCI);
        OUTREG(R128_BM_CHUNK_0_VAL, chunk);
        OUTREG(R128_PCI_GART_PAGE, 0); /* Ensure PCI GART is used */
    }

    return GL_TRUE;
}
コード例 #8
0
int main(int argc, char **argv)
{
    int            c;
    int            r  = 0;
    int            fd = -1;
    drm_handle_t      handle;
    void           *address;
    char           *pt;
    unsigned long  count;
    unsigned long  offset;
    unsigned long  size;
    drm_context_t  context;
    int            loops;
    char           buf[1024];
    int            i;
    drmBufInfoPtr  info;
    drmBufMapPtr   bufs;
    drmLockPtr     lock;
    int            secs;

    while ((c = getopt(argc, argv,
		       "lc:vo:O:f:s:w:W:b:r:R:P:L:C:XS:B:F:")) != EOF)
	switch (c) {
	case 'F':
	    count  = strtoul(optarg, NULL, 0);
	    if (!fork()) {
		dup(fd);
		sleep(count);
	    }
	    close(fd);
	    break;
	case 'v': getversion(fd);                                        break;
	case 'X':
	    if ((r = drmCreateContext(fd, &context))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    printf( "Got %d\n", context);
	    break;
	case 'S':
	    process_sigio(optarg);
	    break;
	case 'C':
	    if ((r = drmSwitchToContext(fd, strtoul(optarg, NULL, 0)))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    break;
	case 'c':
	    if ((r = drmSetBusid(fd,optarg))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    break;
	case 'o':
	    if ((fd = drmOpen(optarg, NULL)) < 0) {
		drmError(fd, argv[0]);
		return 1;
	    }
	    break;
	case 'O':
	    if ((fd = drmOpen(NULL, optarg)) < 0) {
		drmError(fd, argv[0]);
		return 1;
	    }
	    break;
	case 'B':		/* Test buffer allocation */
	    count  = strtoul(optarg, &pt, 0);
	    size   = strtoul(pt+1, &pt, 0);
	    secs   = strtoul(pt+1, NULL, 0);
	    {
		drmDMAReq      dma;
		int            *indices, *sizes;

		indices = alloca(sizeof(*indices) * count);
		sizes   = alloca(sizeof(*sizes)   * count);
		dma.context         = context;
		dma.send_count      = 0;
		dma.request_count   = count;
		dma.request_size    = size;
		dma.request_list    = indices;
		dma.request_sizes   = sizes;
		dma.flags           = DRM_DMA_WAIT;
		if ((r = drmDMA(fd, &dma))) {
		    drmError(r, argv[0]);
		    return 1;
		}
		for (i = 0; i < dma.granted_count; i++) {
		    printf("%5d: index = %d, size = %d\n",
			   i, dma.request_list[i], dma.request_sizes[i]);
		}
		sleep(secs);
		drmFreeBufs(fd, dma.granted_count, indices);
	    }
	    break;
	case 'b':
	    count   = strtoul(optarg, &pt, 0);
	    size    = strtoul(pt+1, NULL, 0);
	    if ((r = drmAddBufs(fd, count, size, 0, 65536)) < 0) {
		drmError(r, argv[0]);
		return 1;
	    }
	    if (!(info = drmGetBufInfo(fd))) {
		drmError(0, argv[0]);
		return 1;
	    }
	    for (i = 0; i < info->count; i++) {
		printf("%5d buffers of size %6d (low = %d, high = %d)\n",
		       info->list[i].count,
		       info->list[i].size,
		       info->list[i].low_mark,
		       info->list[i].high_mark);
	    }
	    if ((r = drmMarkBufs(fd, 0.50, 0.80))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    if (!(info = drmGetBufInfo(fd))) {
		drmError(0, argv[0]);
		return 1;
	    }
	    for (i = 0; i < info->count; i++) {
		printf("%5d buffers of size %6d (low = %d, high = %d)\n",
		       info->list[i].count,
		       info->list[i].size,
		       info->list[i].low_mark,
		       info->list[i].high_mark);
	    }
	    printf("===== /proc/dri/0/mem =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem");
	    system(buf);
#if 1
	    if (!(bufs = drmMapBufs(fd))) {
		drmError(0, argv[0]);
		return 1;
	    }
	    printf("===============================\n");
	    printf( "%d bufs\n", bufs->count);
	    for (i = 0; i < bufs->count; i++) {
		printf( "  %4d: %8d bytes at %p\n",
			i,
			bufs->list[i].total,
			bufs->list[i].address);
	    }
	    printf("===== /proc/dri/0/vma =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma");
	    system(buf);
#endif
	    break;
	case 'f':
	    offset  = strtoul(optarg, &pt, 0);
	    size    = strtoul(pt+1, NULL, 0);
	    handle  = 0;
	    if ((r = drmAddMap(fd, offset, size,
			       DRM_FRAME_BUFFER, 0, &handle))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    printf("0x%08lx:0x%04lx added\n", offset, size);
	    printf("===== /proc/dri/0/mem =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem");
	    system(buf);
	    break;
	case 'r':
	case 'R':
	    offset  = strtoul(optarg, &pt, 0);
	    size    = strtoul(pt+1, NULL, 0);
	    handle  = 0;
	    if ((r = drmAddMap(fd, offset, size,
			       DRM_REGISTERS,
			       c == 'R' ? DRM_READ_ONLY : 0,
			       &handle))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    printf("0x%08lx:0x%04lx added\n", offset, size);
	    printf("===== /proc/dri/0/mem =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem");
	    system(buf);
	    break;
	case 's':
	    size = strtoul(optarg, &pt, 0);
	    handle = 0;
	    if ((r = drmAddMap(fd, 0, size,
			       DRM_SHM, DRM_CONTAINS_LOCK,
			       &handle))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    printf("0x%04lx byte shm added at 0x%08lx\n", size, handle);
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/vm");
	    system(buf);
	    break;
	case 'P':
	    offset  = strtoul(optarg, &pt, 0);
	    size    = strtoul(pt+1, NULL, 0);
	    address = NULL;
	    if ((r = drmMap(fd, offset, size, &address))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
		   offset, size, address, getpid());
	    printf("===== /proc/dri/0/vma =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma");
	    system(buf);
	    mprotect((void *)offset, size, PROT_READ);
	    printf("===== /proc/dri/0/vma =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma");
	    system(buf);
	    break;
	case 'w':
	case 'W':
	    offset  = strtoul(optarg, &pt, 0);
	    size    = strtoul(pt+1, NULL, 0);
	    address = NULL;
	    if ((r = drmMap(fd, offset, size, &address))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
		   offset, size, address, getpid());
	    printf("===== /proc/%d/maps =====\n", getpid());
	    snprintf(buf, sizeof(buf), "cat /proc/%d/maps", getpid());
	    system(buf);
	    printf("===== /proc/dri/0/mem =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem");
	    system(buf);
	    printf("===== /proc/dri/0/vma =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma");
	    system(buf);
	    printf("===== READING =====\n");
	    for (i = 0; i < 0x10; i++)
		printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
	    printf("\n");
	    if (c == 'w') {
		printf("===== WRITING =====\n");
		for (i = 0; i < size; i+=2) {
		    ((char *)address)[i]   = i & 0xff;
		    ((char *)address)[i+1] = i & 0xff;
		}
	    }
	    printf("===== READING =====\n");
	    for (i = 0; i < 0x10; i++)
		printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
	    printf("\n");
	    printf("===== /proc/dri/0/vma =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma");
	    system(buf);
	    break;
	case 'L':
	    context = strtoul(optarg, &pt, 0);
	    offset  = strtoul(pt+1, &pt, 0);
	    size    = strtoul(pt+1, &pt, 0);
	    loops   = strtoul(pt+1, NULL, 0);
	    address = NULL;
	    if ((r = drmMap(fd, offset, size, &address))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    lock       = address;
#if 1
	    {
		int            counter = 0;
		struct timeval loop_start, loop_end;
		struct timeval lock_start, lock_end;
		double         wt;
#define HISTOSIZE 9
		int            histo[HISTOSIZE];
		int            output = 0;
		int            fast   = 0;

		if (loops < 0) {
		    loops = -loops;
		    ++output;
		}

		for (i = 0; i < HISTOSIZE; i++) histo[i] = 0;

		gettimeofday(&loop_start, NULL);
		for (i = 0; i < loops; i++) {
		    gettimeofday(&lock_start, NULL);
		    DRM_LIGHT_LOCK_COUNT(fd,lock,context,fast);
		    gettimeofday(&lock_end, NULL);
		    DRM_UNLOCK(fd,lock,context);
		    ++counter;
		    wt = usec(&lock_end, &lock_start);
		    if      (wt <=      2.5) ++histo[8];
		    if      (wt <       5.0) ++histo[0];
		    else if (wt <      50.0) ++histo[1];
		    else if (wt <     500.0) ++histo[2];
		    else if (wt <    5000.0) ++histo[3];
		    else if (wt <   50000.0) ++histo[4];
		    else if (wt <  500000.0) ++histo[5];
		    else if (wt < 5000000.0) ++histo[6];
		    else                     ++histo[7];
		    if (output) printf( "%.2f uSec, %d fast\n", wt, fast);
		}
		gettimeofday(&loop_end, NULL);
		printf( "Average wait time = %.2f usec, %d fast\n",
			usec(&loop_end, &loop_start) /  counter, fast);
		printf( "%9d <=     2.5 uS\n", histo[8]);
		printf( "%9d <        5 uS\n", histo[0]);
		printf( "%9d <       50 uS\n", histo[1]);
		printf( "%9d <      500 uS\n", histo[2]);
		printf( "%9d <     5000 uS\n", histo[3]);
		printf( "%9d <    50000 uS\n", histo[4]);
		printf( "%9d <   500000 uS\n", histo[5]);
		printf( "%9d <  5000000 uS\n", histo[6]);
		printf( "%9d >= 5000000 uS\n", histo[7]);
	    }
#else
	    printf( "before lock: 0x%08x\n", lock->lock);
	    printf( "lock: 0x%08x\n", lock->lock);
	    sleep(5);
	    printf( "unlock: 0x%08x\n", lock->lock);
#endif
	    break;
	default:
	    fprintf( stderr, "Usage: drmstat [options]\n" );
	    return 1;
	}

    return r; 
}